From 48ae1256759d411ba68ae5bcb67ae7058f30a3bc Mon Sep 17 00:00:00 2001 From: IgorA Date: Fri, 14 Sep 2018 16:10:51 +0000 Subject: [PATCH] add new program 'cnc_editor' git-svn-id: svn://kolibrios.org@7360 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/other/cnc_editor/build_en.bat | 9 + programs/other/cnc_editor/build_ru.bat | 9 + programs/other/cnc_editor/cnc_editor.asm | 2061 +++++++++++++++++ programs/other/cnc_editor/cnc_editor.inc | 1728 ++++++++++++++ programs/other/cnc_editor/doc/but_01.png | Bin 0 -> 360 bytes programs/other/cnc_editor/doc/but_02.png | Bin 0 -> 645 bytes programs/other/cnc_editor/doc/but_03.png | Bin 0 -> 491 bytes programs/other/cnc_editor/doc/but_04.png | Bin 0 -> 439 bytes programs/other/cnc_editor/doc/but_05.png | Bin 0 -> 496 bytes programs/other/cnc_editor/doc/but_06.png | Bin 0 -> 498 bytes programs/other/cnc_editor/doc/but_07.png | Bin 0 -> 346 bytes programs/other/cnc_editor/doc/but_08.png | Bin 0 -> 263 bytes programs/other/cnc_editor/doc/but_09.png | Bin 0 -> 265 bytes programs/other/cnc_editor/doc/but_10.png | Bin 0 -> 308 bytes programs/other/cnc_editor/doc/but_11.png | Bin 0 -> 375 bytes programs/other/cnc_editor/doc/but_12.png | Bin 0 -> 229 bytes programs/other/cnc_editor/doc/but_13.png | Bin 0 -> 352 bytes programs/other/cnc_editor/doc/but_14.png | Bin 0 -> 351 bytes programs/other/cnc_editor/doc/but_15.png | Bin 0 -> 239 bytes programs/other/cnc_editor/doc/cnc_01.png | Bin 0 -> 24075 bytes programs/other/cnc_editor/doc/cnc_02.png | Bin 0 -> 36675 bytes programs/other/cnc_editor/doc/cnc_03.png | Bin 0 -> 3523 bytes programs/other/cnc_editor/doc/cnc_04.png | Bin 0 -> 2905 bytes programs/other/cnc_editor/doc/cnc_05.png | Bin 0 -> 3014 bytes programs/other/cnc_editor/doc/cnc_06.png | Bin 0 -> 2439 bytes programs/other/cnc_editor/doc/readme_ru.htm | 114 + programs/other/cnc_editor/kolibri.NC | 789 +++++++ programs/other/cnc_editor/objects.png | Bin 0 -> 975 bytes programs/other/cnc_editor/tl_sys_16.png | Bin 0 -> 1425 bytes programs/other/cnc_editor/toolbar.png | Bin 0 -> 3095 bytes programs/other/cnc_editor/wnd_new_file.inc | 587 +++++ .../other/cnc_editor/wnd_point_coords.inc | 302 +++ programs/other/cnc_editor/wnd_scale.inc | 181 ++ 33 files changed, 5780 insertions(+) create mode 100644 programs/other/cnc_editor/build_en.bat create mode 100644 programs/other/cnc_editor/build_ru.bat create mode 100644 programs/other/cnc_editor/cnc_editor.asm create mode 100644 programs/other/cnc_editor/cnc_editor.inc create mode 100644 programs/other/cnc_editor/doc/but_01.png create mode 100644 programs/other/cnc_editor/doc/but_02.png create mode 100644 programs/other/cnc_editor/doc/but_03.png create mode 100644 programs/other/cnc_editor/doc/but_04.png create mode 100644 programs/other/cnc_editor/doc/but_05.png create mode 100644 programs/other/cnc_editor/doc/but_06.png create mode 100644 programs/other/cnc_editor/doc/but_07.png create mode 100644 programs/other/cnc_editor/doc/but_08.png create mode 100644 programs/other/cnc_editor/doc/but_09.png create mode 100644 programs/other/cnc_editor/doc/but_10.png create mode 100644 programs/other/cnc_editor/doc/but_11.png create mode 100644 programs/other/cnc_editor/doc/but_12.png create mode 100644 programs/other/cnc_editor/doc/but_13.png create mode 100644 programs/other/cnc_editor/doc/but_14.png create mode 100644 programs/other/cnc_editor/doc/but_15.png create mode 100644 programs/other/cnc_editor/doc/cnc_01.png create mode 100644 programs/other/cnc_editor/doc/cnc_02.png create mode 100644 programs/other/cnc_editor/doc/cnc_03.png create mode 100644 programs/other/cnc_editor/doc/cnc_04.png create mode 100644 programs/other/cnc_editor/doc/cnc_05.png create mode 100644 programs/other/cnc_editor/doc/cnc_06.png create mode 100644 programs/other/cnc_editor/doc/readme_ru.htm create mode 100644 programs/other/cnc_editor/kolibri.NC create mode 100644 programs/other/cnc_editor/objects.png create mode 100644 programs/other/cnc_editor/tl_sys_16.png create mode 100644 programs/other/cnc_editor/toolbar.png create mode 100644 programs/other/cnc_editor/wnd_new_file.inc create mode 100644 programs/other/cnc_editor/wnd_point_coords.inc create mode 100644 programs/other/cnc_editor/wnd_scale.inc diff --git a/programs/other/cnc_editor/build_en.bat b/programs/other/cnc_editor/build_en.bat new file mode 100644 index 0000000000..0fdd2a0c7b --- /dev/null +++ b/programs/other/cnc_editor/build_en.bat @@ -0,0 +1,9 @@ +if not exist bin mkdir bin +@copy *.nc bin\*.nc + +@erase lang.inc +@echo lang fix en >lang.inc + +@fasm.exe -m 32768 cnc_editor.asm bin\cnc_editor.kex +@kpack bin\cnc_editor.kex +pause \ No newline at end of file diff --git a/programs/other/cnc_editor/build_ru.bat b/programs/other/cnc_editor/build_ru.bat new file mode 100644 index 0000000000..f63c4cd7b6 --- /dev/null +++ b/programs/other/cnc_editor/build_ru.bat @@ -0,0 +1,9 @@ +if not exist bin mkdir bin +@copy *.nc bin\*.nc + +@erase lang.inc +@echo lang fix ru >lang.inc + +@fasm.exe -m 32768 cnc_editor.asm bin\cnc_editor.kex +@kpack bin\cnc_editor.kex +pause \ No newline at end of file diff --git a/programs/other/cnc_editor/cnc_editor.asm b/programs/other/cnc_editor/cnc_editor.asm new file mode 100644 index 0000000000..d6244d0567 --- /dev/null +++ b/programs/other/cnc_editor/cnc_editor.asm @@ -0,0 +1,2061 @@ +use32 + org 0 + db 'MENUET01' + dd 1,start,i_end,mem,stacktop,0,sys_path + +include 'd:/kolibri/svn/programs/macros.inc' +include 'd:/kolibri/svn/programs/proc32.inc' +include 'd:/kolibri/svn/programs/KOSfuncs.inc' +include 'd:/kolibri/svn/programs/load_img.inc' +include 'd:/kolibri/svn/programs/develop/libraries/libs-dev/libimg/libimg.inc' +include 'd:/kolibri/svn/programs/develop/libraries/box_lib/trunk/box_lib.mac' +include 'lang.inc' +include 'cnc_editor.inc' +include '../../develop/info3ds/info_fun_float.inc' + +@use_library_mem mem.Alloc,mem.Free,mem.ReAlloc,dll.Load +caption db 'CNC editor 14.09.18',0 ;подпись окна + +run_file_70 FileInfoBlock + +offs_last_timer dd 0 ;последний сдвиг показаный в функции таймера + +IMAGE_TOOLBAR_ICON_SIZE equ 16*16*3 +image_data_toolbar dd 0 ;указатель на временную память. для нужен преобразования изображения +icon_tl_sys dd 0 ;указатель на память для хранения системных иконок +icon_toolbar dd 0 ;указатель на память для хранения иконок объектов + +include 'wnd_point_coords.inc' +include 'wnd_scale.inc' +include 'wnd_new_file.inc' + +align 4 +start: + load_libraries l_libs_start,l_libs_end + ;проверка на сколько удачно загузилась библиотека + mov ebp,lib_0 + cmp dword [ebp+ll_struc_size-4],0 + jz @f + mcall SF_TERMINATE_PROCESS + @@: + mcall SF_STYLE_SETTINGS,SSF_GET_COLORS,sc,sizeof.system_colors + mcall SF_SET_EVENTS_MASK,0xC0000027 + stdcall [OpenDialog_Init],OpenDialog_data ;подготовка диалога + + stdcall [buf2d_create], buf_0 ;создание буфера + + ;шрифт делаем до создания панели (для экономии указателя image_data_toolbar) + include_image_file '..\..\fs\kfar\trunk\font6x9.bmp', image_data_toolbar, buf_1.w,buf_1.h + stdcall [buf2d_create_f_img], buf_1,[image_data_toolbar] ;создаем буфер + stdcall mem.Free,[image_data_toolbar] ;освобождаем память + stdcall [buf2d_conv_24_to_8], buf_1,1 ;делаем буфер прозрачности 8 бит + stdcall [buf2d_convert_text_matrix], buf_1 + mov eax,[buf_1.h] + shr eax,8 + mov [font_h],eax + + include_image_file 'toolbar.png', image_data_toolbar + + mov dword[w_scr_t1.type],1 + stdcall dword[tl_data_init], tree1 + ;системные иконки 16*16 для tree_list + include_image_file 'tl_sys_16.png', icon_tl_sys + mov eax,dword[icon_tl_sys] + mov dword[tree1.data_img_sys],eax + + include_image_file 'objects.png', icon_toolbar + mov eax,dword[icon_toolbar] + mov dword[tree1.data_img],eax + + ;*** установка времени для таймера + mcall SF_SYSTEM_GET,SSF_TIME_COUNT + mov [last_time],eax + + ;call but_new_file + +align 4 +red_win: + call draw_window + +align 4 +still: + mcall SF_SYSTEM_GET,SSF_TIME_COUNT + mov ebx,[last_time] + add ebx,10 ;задержка + cmp ebx,eax + jge @f + mov ebx,eax + @@: + sub ebx,eax + mcall SF_WAIT_EVENT_TIMEOUT + cmp eax,0 + jne @f + call timer_funct + jmp still + @@: + + cmp al,1 + jz red_win + cmp al,2 + jz key + cmp al,3 + jz button + cmp al,6 + jne @f + mcall SF_THREAD_INFO,procinfo,-1 + cmp ax,word[procinfo.window_stack_position] + jne @f ;окно не активно + call mouse + @@: + jmp still + +align 4 +mouse: + push eax ebx ecx + mcall SF_MOUSE_GET,SSF_BUTTON_EXT + bt eax,8 + jnc @f + ;mouse l. but. press + call mouse_left_d + jmp .end_l + @@: + ;bt eax,0 + ;jnc @f + ;mouse l. but. move + ;call mouse_left_m + ;jmp .end_l + ;@@: + bt eax,16 + jnc .end_l + ;mouse l. but. up + call mouse_left_u + ;jmp .end_l + .end_l: + bt eax,9 + jnc @f + ;mouse r. but. press + call mouse_right_d + ;jmp .end_r + @@: + ;bt eax,1 + ;jnc @f + ;mouse r. but. move + ;call mouse_right_m + ;jmp .end_r + ;@@: + ;.end_r: + + call buf_get_mouse_coord + cmp eax,-1 + je .end0 + shl eax,1 + sub eax,[buf_0.w] + sar eax,1 + mov [mouse_prop_x],eax + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end0 + cmp [eax+Figure.OType],'Fig' + je @f + cmp [eax+Figure.OType],'Obj' + je .end1 + jmp .end0 + .end1: + mov eax,ObjData + @@: + mov ecx,eax + shl ebx,1 + sub ebx,[buf_0.h] + sar ebx,1 + mov [mouse_prop_y],ebx + + mcall SF_MOUSE_GET,SSF_SCROLL_DATA + test ax,ax + jz .end0 + finit + fld qword[zoom_plus] + fld1 + fsubp + fld st0 ;for Y coord + + ;for X coord + fild dword[mouse_prop_x] + fmulp st1,st0 + + mov ebx,eax + test ax,0x8000 + jnz .decr + ;увеличение масштаба + fchs + fild dword[ecx+Figure.MCentrX] ;add old value + fmul qword[zoom_plus] + faddp + + fld qword[ecx+Figure.MScale] + fmul qword[zoom_plus] + ;if (Figure.MScale>16.0) + ;... + jmp @f + .decr: + ;уменьшение масштаба + fild dword[ecx+Figure.MCentrX] ;add old value + fdiv qword[zoom_plus] + faddp + + fld qword[ecx+Figure.MScale] + fdiv qword[zoom_plus] + fld1 + fcomp + fstsw ax + sahf + jbe @f + ;if (Figure.MScale<1.0) + ffree st0 + fincstp + ffree st0 + fincstp + fldz ;default Figure.MCentrX + fld1 ;default Figure.MScale + mov dword[ecx+Figure.MCentrY],0 + @@: + fstp qword[ecx+Figure.MScale] + fistp dword[ecx+Figure.MCentrX] + + ;for Y coord + fild dword[mouse_prop_y] + fmulp st1,st0 + test bx,0x8000 + jnz .decr_y + ;увеличение масштаба + fild dword[ecx+Figure.MCentrY] ;add old value + fmul qword[zoom_plus] + faddp + jmp @f + .decr_y: + ;уменьшение масштаба + fchs + fild dword[ecx+Figure.MCentrY] ;add old value + fdiv qword[zoom_plus] + faddp + @@: + fistp dword[ecx+Figure.MCentrY] + + mov dword[offs_last_timer],0 + .end0: + + stdcall [tl_mouse], tree1 + pop ecx ebx eax + ret + +;output: +; eax - buffer coord X (если курсор за буфером -1) +; ebx - buffer coord Y (если курсор за буфером -1) +align 4 +proc buf_get_mouse_coord + mcall SF_MOUSE_GET,SSF_WINDOW_POSITION + cmp ax,word[buf_0.t] + jl .no_buf ;не попали в окно буфера по оси y + mov ebx,eax + shr ebx,16 + cmp bx,word[buf_0.l] + jl .no_buf ;не попали в окно буфера по оси x + + and eax,0xffff ;оставляем координату y + sub ax,word[buf_0.t] + cmp eax,[buf_0.h] + jg .no_buf + sub bx,word[buf_0.l] + cmp ebx,[buf_0.w] + jg .no_buf + xchg eax,ebx + jmp .end_f + .no_buf: + xor eax,eax + not eax + xor ebx,ebx + not ebx + .end_f: + ret +endp + +align 4 +proc timer_funct + pushad + mcall SF_SYSTEM_GET,SSF_TIME_COUNT + mov [last_time],eax + + ;просматриваем выделенный блок данных + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_f + cmp dword[offs_last_timer],eax + je .end_f + ;если выделенный блок данных не совпадает с последним запомненным + mov dword[offs_last_timer],eax + + stdcall get_object_data,eax + or ecx,ecx + jz .end_oblo + stdcall draw_obj2d,ecx + stdcall [buf2d_draw], buf_0 + jmp .end_f + .end_oblo: + + cmp [eax+Figure.OType],'Fig' + jne .end_fblo + stdcall draw_fig2d,eax + stdcall [buf2d_draw], buf_0 + jmp .end_f + .end_fblo: + + .end_f: + + popad + ret +endp + +align 4 +draw_window: +pushad + mcall SF_REDRAW,SSF_BEGIN_DRAW + + ; *** рисование главного окна (выполняется 1 раз при запуске) *** + mov edx,[sc.work] + or edx,(3 shl 24)+0x10000000+0x20000000 + mov edi,caption + mcall SF_CREATE_WINDOW,(20 shl 16)+599,(20 shl 16)+415 + + mcall SF_THREAD_INFO,procinfo,-1 + mov eax,dword[procinfo.box.height] + cmp eax,120 + jge @f + mov eax,120 ;min size + @@: + sub eax,65 + mov dword[tree1.box_height],eax + mov word[w_scr_t1.y_size],ax ;новые размеры скроллинга + mov ebx,dword[procinfo.box.width] + cmp ebx,270 + jge @f + mov ebx,270 + @@: + sub ebx,215 + cmp eax,dword[buf_0.h] ;смотрим размер буфера + jne @f + cmp ebx,dword[buf_0.w] + jne @f + jmp .end0 + @@: + stdcall [buf2d_resize],buf_0,ebx,eax,1 + mov eax,ObjData + mov ecx,[eax+Object.FigCount] + or ecx,ecx + jz .end0 + mov eax,[eax+Object.FigData] + xor edx,edx + .cycle0: + stdcall FigCalculateSizes,[eax+4*edx],0 + inc edx + loop .cycle0 + stdcall ObjCalculateScale,ObjData + mov dword[offs_last_timer],0 + call timer_funct + .end0: + + ; *** создание кнопок на панель *** + mcall SF_DEFINE_BUTTON,(5 shl 16)+20,(5 shl 16)+20,3,, [sc.work_button] + + mov ebx,(30 shl 16)+20 + mov edx,4 ;0x4000000? + int 0x40 ;open + + add ebx,25 shl 16 + mov edx,5 + int 0x40 ;save + + add ebx,30 shl 16 + mov edx,6 + int 0x40 ;captions on off + + add ebx,25 shl 16 + mov edx,7 + int 0x40 ;figure move up + + add ebx,25 shl 16 + mov edx,8 + int 0x40 ;figure move down + + add ebx,25 shl 16 + mov edx,9 + int 0x40 ;sel points dlg + + add ebx,25 shl 16 + mov edx,10 + int 0x40 ;sel points move up + + add ebx,25 shl 16 + mov edx,11 + int 0x40 ;sel points move down + + add ebx,25 shl 16 + mov edx,12 + int 0x40 ;copy to clipboard + + add ebx,25 shl 16 + mov edx,13 + int 0x40 ;paste from clipboard + + add ebx,25 shl 16 + mov edx,14 + int 0x40 ;sel points del + + add ebx,30 shl 16 + mov edx,15 + int 0x40 ;restore zoom + + add ebx,30 shl 16 + mov edx,16 + int 0x40 ;.png + + add ebx,25 shl 16 + mov edx,17 + int 0x40 ;options scale + + ; *** рисование иконок на кнопках *** + mcall SF_PUT_IMAGE,[image_data_toolbar],(16 shl 16)+16,(7 shl 16)+7 ;icon new + + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;icon open + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;icon save + int 0x40 + + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(30 shl 16) ;captions on off + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;figure move up + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;figure move down + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;sel points dlg + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;sel points move up + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;sel points move down + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;copy to clipboard + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;paste from clipboard + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;sel points del + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(30 shl 16) ;restore zoom + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(30 shl 16) ;.png + int 0x40 + add ebx,IMAGE_TOOLBAR_ICON_SIZE + add edx,(25 shl 16) ;options scale + int 0x40 + + mov dword[w_scr_t1.all_redraw],1 + stdcall [tl_draw], tree1 + stdcall [buf2d_draw], buf_0 + + mcall SF_REDRAW,SSF_END_DRAW +popad + ret + +align 4 +key: + mcall SF_GET_KEY + cmp dword[el_focus], tree1 + jne @f + stdcall [tl_key], tree1 + jmp .end0 + @@: + + cmp ah,178 ;Up + jne @f + call but_selection_move_up + jmp .end0 + @@: + cmp ah,177 ;Down + jne @f + call but_selection_move_down + jmp .end0 + @@: + cmp ah,176 ;Left + jne @f + call but_selection_move_up + jmp .end0 + @@: + cmp ah,179 ;Right + jne @f + call but_selection_move_down + jmp .end0 + @@: + cmp ah,182 ;Delete + jne @f + call but_sel_points_del + jmp .end0 + @@: + + mov ecx,eax + mcall SF_KEYBOARD,SSF_GET_CONTROL_KEYS + bt eax,2 ;left Ctrl + jc .key_Ctrl + bt eax,3 ;right Ctrl + jc .key_Ctrl + jmp .end0 + .key_Ctrl: + cmp ch,15 ;111 ;Ctrl+O + jne @f + call but_open_file + @@: + cmp ch,19 ;115 ;Ctrl+S + jne @f + call but_save_file + @@: + cmp ch,14 ;110 ;Ctrl+N + jne @f + call but_new_file + @@: + cmp ch,1 ;97 ;Ctrl+A + jne @f + call but_sel_points_all + @@: + .end0: + jmp still + + +align 4 +button: + mcall SF_GET_BUTTON + cmp ah,3 + jne @f + call but_new_file + jmp still + @@: + cmp ah,4 + jne @f + call but_open_file + jmp still + @@: + cmp ah,5 + jne @f + call but_save_file + jmp still + @@: + cmp ah,6 + jne @f + call but_captions_on_off + jmp still + @@: + cmp ah,7 + jne @f + call but_sel_figure_move_up + jmp still + @@: + cmp ah,8 + jne @f + call but_sel_figure_move_down + jmp still + @@: + cmp ah,9 + jne @f + call but_dlg_point_coords + jmp still + @@: + cmp ah,10 + jne @f + call but_sel_points_move_up + jmp still + @@: + cmp ah,11 + jne @f + call but_sel_points_move_down + jmp still + @@: + cmp ah,12 + jne @f + call but_clipboard_copy_points + jmp still + @@: + cmp ah,13 + jne @f + call but_clipboard_paste_points + jmp still + @@: + cmp ah,14 + jne @f + call but_sel_points_del + jmp still + @@: + cmp ah,15 + jne @f + call but_restore_zoom + jmp still + @@: + cmp ah,16 + jne @f + call but_save_png + jmp still + @@: + cmp ah,17 + jne @f + call but_dlg_opt_scale + jmp still + @@: + + ;cmp ah,18 + ;jne @f + ;call but_... + ;jmp still + ;@@: + cmp ah,1 + jne still +.exit: + stdcall [buf2d_delete],buf_0 + stdcall mem.Free,[image_data_toolbar] + stdcall mem.Free,[open_file_data] + mcall SF_TERMINATE_PROCESS + + +align 4 +but_new_file: + cmp byte[wnd_n_file],0 + jne .end_f +pushad + mcall SF_CREATE_THREAD,1,start_n_file,thread_n_file +popad + .end_f: + ret + +align 4 +open_file_data dd 0 ;указатель на память для открытия файлов +open_file_size dd 0 ;размер открытого файла + +align 4 +but_open_file: + pushad + copy_path open_dialog_name,communication_area_default_path,file_name,0 + mov [OpenDialog_data.type],0 + stdcall [OpenDialog_Start],OpenDialog_data + cmp [OpenDialog_data.status],2 + je .end_open_file + ;код при удачном открытии диалога + + mov [run_file_70.Function], SSF_GET_INFO + mov [run_file_70.Position], 0 + mov [run_file_70.Flags], 0 + mov dword[run_file_70.Count], 0 + mov dword[run_file_70.Buffer], open_b + mov byte[run_file_70+20], 0 + mov dword[run_file_70.FileName], openfile_path + mcall SF_FILE,run_file_70 + + ;mov eax,dword[open_b+32] + ;mov edi,txt_buf + ;stdcall convert_int_to_str,20 + ;notify_window_run txt_buf + + mov ecx,dword[open_b+32] ;+32 qword: размер файла в байтах + inc ecx ;for text files + stdcall mem.ReAlloc,[open_file_data],ecx + mov [open_file_data],eax + dec ecx ;for text files + mov byte[eax+ecx],0 ;for text files + + mov [run_file_70.Function], SSF_READ_FILE + mov [run_file_70.Position], 0 + mov [run_file_70.Flags], 0 + mov dword[run_file_70.Count], ecx + m2m dword[run_file_70.Buffer], dword[open_file_data] + mov byte[run_file_70+20], 0 + mov dword[run_file_70.FileName], openfile_path + mcall SF_FILE,run_file_70 ;загружаем файл изображения + test eax,eax + jnz .end_open_file + cmp ebx,0xffffffff + je .end_open_file + + mov [open_file_size],ebx + mcall SF_SET_CAPTION,1,openfile_path + + ;--- + stdcall FileInit,[open_file_data],[open_file_size] + stdcall [buf2d_clear], buf_0, [buf_0.color] ;чистим буфер + stdcall [buf2d_draw], buf_0 ;обновляем буфер на экране + .end_open_file: + popad + ret + +align 4 +proc but_save_file +locals + pCou dd ? + pData dd ? +endl + pushad + copy_path open_dialog_name,communication_area_default_path,file_name,0 + mov [OpenDialog_data.type],1 + stdcall [OpenDialog_Start],OpenDialog_data + cmp [OpenDialog_data.status],2 + je .end_save_file + ;код при удачном открытии диалога + + ;*** определение примерного размера файла + call get_file_save_size + stdcall mem.ReAlloc,[open_file_data],ecx + mov [open_file_data],eax + mov [open_file_size],ecx + + ;clear memory + mov edi,eax + xor eax,eax + shr ecx,2 + rep stosd + + ;*** пишем информацию в память + mov edi,[open_file_data] + mov ebx,ObjData + mov edx,[ebx+Object.FigCount] + or edx,edx + jz .cycle1end + mov esi,[ebx+Object.FigData] +align 4 + .cycle1: ;цикл по фигурам + ;param 1 + mov eax,[esi] + or eax,eax + jz .err_save + mov eax,[eax+Figure.PoiCount] + mov [pCou],eax + or eax,eax + jnz @f + mov eax,[esi] + lea eax,[eax+Figure.Caption] + stdcall str_cat,edi,eax + stdcall str_len,edi + add edi,eax + stdcall str_cat,edi,txt_nl + @@: + cmp dword[pCou],0 + je .cycle2end + mov eax,[esi] + mov eax,[eax+Figure.PoiData] + mov [pData],eax + mov word[NumberSymbolsAD],8 +align 4 + .cycle2: ;цикл по точкам + stdcall str_cat,edi,txt_s_poi + ;param 1 + push edi esi + mov esi,[pData] + lea esi,[esi+Point.CoordX] + mov edi,Data_Double + movsd + movsd + pop esi edi + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,edi,Data_String + stdcall str_cat,edi,txt_s_poi_Y + ;param 2 + push edi esi + mov esi,[pData] + lea esi,[esi+Point.CoordY] + mov edi,Data_Double + movsd + movsd + pop esi edi + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,edi,Data_String + ; + stdcall str_cat,edi,txt_nl + add dword[pData],sizeof.Point + dec dword[pCou] + jnz .cycle2 + .cycle2end: + add esi,4 + dec edx + jnz .cycle1 + .cycle1end: + + jmp @f + .err_save: + notify_window_run txt_err_save_txt_file_1 + @@: + + ;*** определение параметров файла + mov edi,[open_file_data] + stdcall str_len,edi + ;;cmp eax,[open_file_size] + mov [run_file_70.Count],eax ;размер файла + + ;*** сохраняем файл + mov [run_file_70.Function], SSF_CREATE_FILE + mov [run_file_70.Position], 0 + mov [run_file_70.Flags], 0 + mov ebx, dword[open_file_data] + mov [run_file_70.Buffer], ebx + mov byte[run_file_70+20], 0 + mov dword[run_file_70.FileName], openfile_path + mcall SF_FILE,run_file_70 + or eax,eax + jz .end_save_file + or ebx,ebx + jnz .end_save_file + ;сообщение о неудачном сохранении + notify_window_run txt_err_save_txt_file_0 + .end_save_file: + popad + ret +endp + +;output: +; ecx - memory size for save file +align 4 +proc get_file_save_size uses eax ebx edx esi + mov ecx,100 ;title + mov ebx,ObjData + add ecx,50 ;object + mov edx,[ebx+Object.FigCount] + or edx,edx + jz .cycle1end + mov esi,[ebx+Object.FigData] +align 4 + .cycle1: ; цикл по фигурам + add ecx,80 ;figure + mov eax,[esi] + or eax,eax + jz @f + mov eax,[eax+Figure.PoiCount] + imul eax,70 + add ecx,eax ;points + @@: + add esi,4 + dec edx + jnz .cycle1 + .cycle1end: + ret +endp + +align 4 +but_captions_on_off: + xor dword[opt_draw],1 + mov dword[offs_last_timer],0 ;для обновления по таймеру + ret + +align 4 +but_sel_figure_move_up: + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_fblo + cmp [eax+Figure.OType],'Fig' + jne .end_fblo + stdcall found_parent_obj,eax + or eax,eax + jz .end_f ;if not found + or ecx,ecx + jz .fig_is_0 ;если фигура в начале списка + mov ebx,[eax+Object.FigData] + mov edx,[ebx+4*ecx] ;передвигаемая фигура + mov edi,[ebx+4*ecx-4] + ;меняем фигуры местами + mov [ebx+4*ecx],edi + mov [ebx+4*ecx-4],edx + ;меняем фигуры в списке + stdcall [tl_node_move_up],tree1 + jmp .end_f + .fig_is_0: + notify_window_run txt_err_figure_is_0 + jmp .end_f + .end_fblo: + notify_window_run txt_err_no_figure_select + .end_f: + popad + ret + +align 4 +but_save_png: + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_save_file + + stdcall get_object_data,eax + or ecx,ecx + jz .end_oblo + stdcall draw_obj2d_png,ecx + jmp .beg0 + .end_oblo: + +; cmp [eax+Figure.OType],'Fig' +; jne .end_fblo +; stdcall draw_fig2d_png,eax +; jmp .beg0 +; .end_fblo: + + jmp .end_save_file + .beg0: + copy_path open_dialog_name,communication_area_default_path,file_name,0 + mov [OpenDialog_data.type],1 + stdcall [OpenDialog_Start],OpenDialog_data + cmp [OpenDialog_data.status],2 + je .end_save_file + ;код при удачном открытии диалога + mov dword[png_data],0 + + ;create image struct + stdcall [img_create], [buf_png.w], [buf_png.h], Image.bpp24 + mov ebx,eax + test eax,eax + jz @f + ;copy foto to image buffer + mov edi,[eax+Image.Data] + mov esi,[buf_png] + mov ecx,[buf_png.w] + mov edx,[buf_png.h] + imul ecx,edx + imul ecx,3 + shr ecx,2 ;OpenGL buffer align to 4 + rep movsd + + ;encode image + stdcall [img_encode], eax, LIBIMG_FORMAT_PNG, 0 + test eax,eax + jz @f + mov [png_data],eax + mov [png_size],ecx + @@: + stdcall [img_destroy],ebx + + ; заполняем структуру для сохранения файла + mov ebx,run_file_70 + mov dword[ebx],SSF_CREATE_FILE + mov eax,[png_size] + mov [ebx+12],eax ;file size + mov eax,[png_data] + mov [ebx+16],eax + mov dword[ebx+FileInfoBlock.FileName], openfile_path + + mcall SF_FILE,run_file_70 + test eax,eax + jnz .save_error + ;notify_window_run openfile_path + jmp @f + .save_error: + ;сообщение о неудачном сохранении + notify_window_run txt_err_save_img_file + @@: + mcall SF_SYS_MISC, SSF_MEM_FREE, [png_data] + .end_save_file: + popad + ret + +;description: +; выделенные точки сдвигаются вверх +align 4 +proc but_sel_points_move_up +locals + pObj dd ? + pFig dd ? + idFig dd ? +endl + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + mov [pFig],eax + stdcall sel_points_get_count,eax + or eax,eax + jz .no_point + + stdcall found_parent_obj,[pFig] + or eax,eax + jz .end_f ;if not found + mov [pObj],eax + mov [idFig],ecx + + ;проверяем выделенные точки + mov eax,[pFig] + mov ecx,[eax+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov ebx,[eax+Figure.PoiData] + xor eax,eax + .cycle0: + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc @f + or eax,eax + jz .point_is_0 + stdcall point_move_up, [pObj],[pFig],[idFig],ebx;,eax + @@: + inc eax + add ebx,sizeof.Point + loop .cycle0 + + ;для обновления по таймеру + mov dword[offs_last_timer],0 + jmp .end_f + .point_is_0: + notify_window_run txt_err_poi_is_0 + jmp .end_f + .no_point: + notify_window_run txt_err_no_point_sel + .end_f: + popad + ret +endp + +;description: +; выделенные точки сдвигаются вниз +align 4 +proc but_sel_points_move_down +locals + pObj dd ? + pFig dd ? + idFig dd ? +endl + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + mov [pFig],eax + stdcall sel_points_get_count,eax + or eax,eax + jz .no_point + + stdcall found_parent_obj,[pFig] + or eax,eax + jz .end_f ;if not found + mov [pObj],eax + mov [idFig],ecx + + ;проверяем выделенные точки + mov eax,[pFig] + mov ecx,[eax+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov ebx,ecx + dec ebx + imul ebx,sizeof.Point + add ebx,[eax+Figure.PoiData] + .cycle0: + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc @f + cmp ecx,[eax+Figure.PoiCount] + je .point_is_last + mov edi,ebx + add edi,sizeof.Point + stdcall point_move_up, [pObj],[pFig],[idFig],edi;,ecx + @@: + sub ebx,sizeof.Point + loop .cycle0 + + ;для обновления по таймеру + mov dword[offs_last_timer],0 + jmp .end_f + .point_is_last: + notify_window_run txt_err_poi_is_last + jmp .end_f + .no_point: + notify_window_run txt_err_no_point_sel + .end_f: + popad + ret +endp + +;description: +; выделение выбранной точки сдвигается вверх +align 4 +proc but_selection_move_up +locals + pFig dd ? +endl + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_fblo + cmp [eax+Figure.OType],'Fig' + jne .end_fblo + + mov [pFig],eax + stdcall sel_points_get_count,eax + cmp eax,1 + jne .no_point + + ;проверяем выделенные точки + mov eax,[pFig] + mov ecx,[eax+Figure.PoiCount] + or ecx,ecx + jz .no_point + dec ecx + jecxz .end_f + mov ebx,[eax+Figure.PoiData] + .cycle0: + add ebx,sizeof.Point + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc @f + btr dword[ebx+Point.Prop],PROP_BIT_SELECT + bts dword[ebx+Point.Prop-sizeof.Point],PROP_BIT_SELECT + xor ecx,ecx + inc ecx ;ecx = 1 - for exit from cycle + @@: + loop .cycle0 + + ;для обновления по таймеру + mov dword[offs_last_timer],0 + jmp .end_f + .no_point: + notify_window_run txt_err_no_point_sel_1 + jmp .end_f + .end_fblo: + ;notify_window_run txt_err_no_figure_select + .end_f: + popad + ret +endp + +;description: +; выделение выбранной точки сдвигается вниз +align 4 +proc but_selection_move_down +locals + pFig dd ? +endl + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_fblo + cmp [eax+Figure.OType],'Fig' + jne .end_fblo + + mov [pFig],eax + stdcall sel_points_get_count,eax + cmp eax,1 + jne .no_point + + ;проверяем выделенные точки + mov eax,[pFig] + mov ecx,[eax+Figure.PoiCount] + or ecx,ecx + jz .no_point + dec ecx + jecxz .end_f + mov ebx,[eax+Figure.PoiData] + .cycle0: + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc @f + btr dword[ebx+Point.Prop],PROP_BIT_SELECT + bts dword[ebx+Point.Prop+sizeof.Point],PROP_BIT_SELECT + xor ecx,ecx + inc ecx ;ecx = 1 - for exit from cycle + @@: + add ebx,sizeof.Point + loop .cycle0 + + ;для обновления по таймеру + mov dword[offs_last_timer],0 + jmp .end_f + .no_point: + notify_window_run txt_err_no_point_sel_1 + jmp .end_f + .end_fblo: + ;notify_window_run txt_err_no_figure_select + .end_f: + popad + ret +endp + +;output: +; eax - couunt new points +align 4 +proc but_clipboard_copy_points uses ebx ecx edx edi esi +locals + pData dd 0 + pBuf dd 0 +endl + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + mov ecx,[eax+Figure.PoiData] + mov [pData],ecx + mov ecx,[eax+Figure.PoiCount] + stdcall sel_points_get_count,eax + or eax,eax + jz .no_point + push eax + imul eax,32 ;for string 'X___.________ Y___.________^^' + stdcall mem.Alloc,eax + mov [pBuf],eax + + mov edx,eax + mov dword[edx+4],0 ;text data + mov dword[edx+8],1 ;code 866 + add edx,12 ;system buffer header size + mov dword[edx],0 + mov word[NumberSymbolsAD],8 +align 4 + .cycle2: ;цикл по точкам + mov esi,[pData] + bt dword[esi+Point.Prop],PROP_BIT_SELECT + jnc .end0 + stdcall str_cat,edx,txt_s_poi + ;param 1 + add esi,Point.CoordX + mov edi,Data_Double + movsd + movsd + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,edx,Data_String + stdcall str_cat,edx,txt_s_poi_Y + ;param 2 + ;;mov esi,[pData] + ;;lea esi,[esi+Point.CoordY] + mov edi,Data_Double + movsd + movsd + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,edx,Data_String + ; + stdcall str_cat,edx,txt_nl + .end0: + add dword[pData],sizeof.Point + loop .cycle2 + .cycle2end: + + mov edx,[pBuf] + add edx,12 + stdcall str_len,edx + sub edx,12 + mov [edx],eax + add eax,12 + mov ecx,eax + mcall SF_CLIPBOARD,SSF_WRITE_CB ;,ecx,edx + stdcall mem.Free,[pBuf] + pop eax + + .no_point: + ret +endp + +;output: +; eax - couunt new points +align 4 +proc but_clipboard_paste_points uses ebx ecx edx esi edi +locals + pFig dd ? + nCount dd ? +endl + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end0 + cmp [eax+Figure.OType],'Fig' + jne .end0 + + mov [pFig],eax + + mcall SF_CLIPBOARD,SSF_GET_SLOT_COUNT + cmp eax,1 + jl .end0 + + mov esi,eax + .cycle0: ;обратный цикл по слотам + dec esi ;номер текущего, проверяемого слота + mcall SF_CLIPBOARD,SSF_READ_CB,esi + cmp eax,1 + je .end0 + cmp eax,-1 + je .end0 + mov ecx,dword[eax] + cmp ecx,5 ;min text size + jl .end0 + cmp dword[eax+4],0 ;text + je @f + cmp esi,1 + jge .cycle0 ;если в буфере не текст, а слотов в буфере несколько, пробуем перейти к верхнему слоту + jmp .end0 + @@: + + mov esi,eax + add esi,12 ;смещение начала текста в буфере + stdcall get_max_points + or eax,eax + jz .end_f + mov [nCount],eax + mov ebx,[pFig] + mov edi,[ebx+Figure.PoiCount] + add [ebx+Figure.PoiCount],eax + add eax,edi + imul eax,sizeof.Point + stdcall mem.ReAlloc,[ebx+Figure.PoiData],eax + mov [ebx+Figure.PoiData],eax + + mov ecx,edi + mov edx,eax +align 4 + .cycle1: ;цикл для снятия выделения со старых точек + btr dword[edx+Point.Prop],PROP_BIT_SELECT + add edx,sizeof.Point + loop .cycle1 + + mov ecx,[nCount] + imul edi,sizeof.Point + add edi,eax + finit +align 4 + .cycle2: ;цикл для добавления новых точек + stdcall PointInit,edi + or eax,eax + jz .cycle2end + bts dword[edi+Point.Prop],PROP_BIT_SELECT + add edi,sizeof.Point + loop .cycle2 + .cycle2end: + or ecx,ecx + jz .end1 + ;уменьшаем объем памяти выделенный для точек + sub [ebx+Figure.PoiCount],ecx + mov eax,[ebx+Figure.PoiCount] + imul eax,sizeof.Point + stdcall mem.ReAlloc,[ebx+Figure.PoiData],eax + mov [ebx+Figure.PoiData],eax + .end1: + stdcall found_parent_obj,ebx ;get figure number in ecx + stdcall figure_update_coords,ObjData,ecx + + mov eax,[nCount] + mov dword[offs_last_timer],0 + jmp .end_f + .end0: + xor eax,eax + .end_f: + ret +endp + +align 4 +proc but_sel_points_del +locals + pFig dd ? + nDel dd ? ;need delete +endl + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + mov [pFig],eax + stdcall sel_points_get_count,eax + or eax,eax + jz .no_point + mov [nDel],eax + + ;проверяем выделенные точки + mov ebx,[pFig] + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + + cmp ecx,eax + jle .no_all + + stdcall found_parent_obj,[pFig] + or eax,eax + jz .end_f ;if not found + mov edi,[ebx+Figure.PoiData] + mov edx,[ebx+Figure.PoiCount] + imul edx,sizeof.Point + add edx,edi + + .cycle0: ;1-я выделенная точка + cmp edi,edx + jge .end0 + bt dword[edi+Point.Prop],PROP_BIT_SELECT + jc .cycle0end + add edi,sizeof.Point + jmp .cycle0 + .cycle0end: + + mov esi,edi ;следущая 1-я не выделенная точка + add esi,sizeof.Point + .cycle1: + cmp esi,edx + jge .end0 + bt dword[esi+Point.Prop],PROP_BIT_SELECT + jnc .cycle1end + add esi,sizeof.Point + jmp .cycle1 + .cycle1end: + + mov ecx,sizeof.Point + rep movsb ;замена выделенной точки + bts dword[esi+Point.Prop-sizeof.Point],PROP_BIT_SELECT ;ставим выделение на точку, что-бы потом ее удалить + + jmp .cycle0 + .end0: + + ;обновление памяти + mov eax,[ebx+Figure.PoiCount] + sub eax,[nDel] + mov [ebx+Figure.PoiCount],eax + imul eax,sizeof.Point + stdcall mem.ReAlloc,[ebx+Figure.PoiData],eax + mov [ebx+Figure.PoiData],eax + + ;перерасчет размеров фигуры + stdcall found_parent_obj,ebx ;get figure number in ecx + stdcall figure_update_coords,ObjData,ecx + + ;для обновления по таймеру + mov dword[offs_last_timer],0 + jmp .end_f + + .no_all: + notify_window_run txt_err_no_point_del + jmp .end_f + .no_point: + notify_window_run txt_err_no_point_sel + .end_f: + popad + ret +endp + +align 4 +proc but_sel_points_all uses eax ecx + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .no_point + cmp [eax+Figure.OType],'Fig' + jne .no_point + + ;проверяем выделенные точки + mov ecx,[eax+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov eax,[eax+Figure.PoiData] + .cycle0: ;1-я выделенная точка + bts dword[eax+Point.Prop],PROP_BIT_SELECT + add eax,sizeof.Point + loop .cycle0 + ;для обновления по таймеру + mov dword[offs_last_timer],0 + .no_point: + ret +endp + +align 4 +proc but_restore_zoom uses eax + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_f + cmp [eax+Figure.OType],'Fig' + je @f + cmp [eax+Figure.OType],'Obj' + je .end0 + jmp .end_f + .end0: + mov eax,ObjData + @@: + finit + fld1 + fstp qword[eax+Figure.MScale] + mov dword[eax+Figure.MCentrX],0 + mov dword[eax+Figure.MCentrY],0 + mov dword[offs_last_timer],0 + .end_f: + ret +endp + +align 4 +but_sel_figure_move_down: + pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_fblo + cmp [eax+Figure.OType],'Fig' + jne .end_fblo + stdcall found_parent_obj,eax + or eax,eax + jz .end_f ;if not found + inc ecx + cmp ecx,[eax+Object.FigCount] + jge .fig_is_last ;если фигура в конце списка + mov ebx,[eax+Object.FigData] + mov edx,[ebx+4*ecx] ;передвигаемая фигура + mov edi,[ebx+4*ecx-4] + ;меняем фигуры местами + mov [ebx+4*ecx],edi + mov [ebx+4*ecx-4],edx + ;меняем фигуры в списке + stdcall [tl_node_move_down],tree1 + jmp .end_f + .fig_is_last: + notify_window_run txt_err_figure_is_last + jmp .end_f + .end_fblo: + notify_window_run txt_err_no_figure_select + .end_f: + popad + ret + +;description: +; запуск окна создания/редактирования точки +align 4 +but_dlg_point_coords: + cmp byte[wnd_run_prop],0 + jne .end_f +pushad + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_fblo + cmp [eax+Figure.OType],'Fig' + jne .end_fblo + mov [wnd_pFig],eax ;фигура + stdcall sel_points_get_count,eax + cmp eax,1 + jne .no_select_1 + stdcall found_parent_obj,[wnd_pFig] + or eax,eax + jz .end0 ;if not found + + mov [wnd_pObj],eax ;obj + mov [wnd_FigN],ecx ;fig number + stdcall sel_points_get_first,[wnd_pFig] + mov [wnd_pPoi],eax + mov edx,[wnd_pFig] + sub eax,[edx+Figure.PoiData] + xor edx,edx + mov ecx,sizeof.Point + div ecx + jmp .end1 + .no_select_1: + or eax,eax + jnz .end_fblo + stdcall found_parent_obj,[wnd_pFig] + or eax,eax + jz .end0 ;if not found + + mov [wnd_pObj],eax ;obj + mov [wnd_FigN],ecx ;fig number + xor eax,eax + mov [wnd_pPoi],eax + mov edx,[wnd_pFig] + mov eax,[edx+Figure.PoiCount] + .end1: + mov [wnd_PoiN],eax + mcall SF_CREATE_THREAD,1,start_prop,thread_coords + jmp .end0 + .end_fblo: + notify_window_run txt_err_no_1_point_sel + ;jmp @f + ;.end_fblo: + ;notify_window_run txt_err_... + .end0: +popad + .end_f: + ret + +align 4 +but_dlg_opt_scale: + cmp byte[wnd_run_scale],0 + jne .end_f +pushad + mcall SF_CREATE_THREAD,1,start_scale,thread_scale +popad + .end_f: + ret + + + +;input: +; buf - указатель на строку, число должно быть в 10 или 16 ричном виде +;output: +; eax - число +align 4 +proc conv_str_to_int uses ebx ecx esi, buf:dword + xor eax,eax + xor ebx,ebx + mov esi,[buf] + + ;на случай если перед числом находятся пробелы + @@: + cmp byte[esi],' ' + jne @f + inc esi + jmp @b + @@: + + ;определение отрицательных чисел + xor ecx,ecx + inc ecx + cmp byte[esi],'-' + jne @f + dec ecx + inc esi + @@: + + cmp word[esi],'0x' + je .load_digit_16 + + .load_digit_10: ;считывание 10-тичных цифр + mov bl,byte[esi] + cmp bl,'0' + jl @f + cmp bl,'9' + jg @f + sub bl,'0' + imul eax,10 + add eax,ebx + inc esi + jmp .load_digit_10 + jmp @f + + .load_digit_16: ;считывание 16-ричных цифр + add esi,2 + .cycle_16: + mov bl,byte[esi] + cmp bl,'0' + jl @f + cmp bl,'f' + jg @f + cmp bl,'9' + jle .us1 + cmp bl,'A' + jl @f ;отсеиваем символы >'9' и <'A' + .us1: ;составное условие + cmp bl,'F' + jle .us2 + cmp bl,'a' + jl @f ;отсеиваем символы >'F' и <'a' + sub bl,32 ;переводим символы в верхний регистр, для упрощения их последущей обработки + .us2: ;составное условие + sub bl,'0' + cmp bl,9 + jle .cor1 + sub bl,7 ;convert 'A' to '10' + .cor1: + shl eax,4 + add eax,ebx + inc esi + jmp .cycle_16 + @@: + cmp ecx,0 ;если число отрицательное + jne @f + sub ecx,eax + mov eax,ecx + @@: + ret +endp + + +;данные для диалога открытия файлов +align 4 +OpenDialog_data: +.type dd 0 ;0 - открыть, 1 - сохранить, 2 - выбрать дтректорию +.procinfo dd procinfo ;+4 +.com_area_name dd communication_area_name ;+8 +.com_area dd 0 ;+12 +.opendir_path dd plugin_path ;+16 +.dir_default_path dd default_dir ;+20 +.start_path dd file_name ;+24 путь к диалогу открытия файлов +.draw_window dd draw_window ;+28 +.status dd 0 ;+32 +.openfile_path dd openfile_path ;+36 путь к открываемому файлу +.filename_area dd filename_area ;+40 +.filter_area dd Filter +.x: +.x_size dw 420 ;+48 ; Window X size +.x_start dw 10 ;+50 ; Window X position +.y: +.y_size dw 320 ;+52 ; Window y size +.y_start dw 10 ;+54 ; Window Y position + +default_dir db '/rd/1',0 + +communication_area_name: + db 'FFFFFFFF_open_dialog',0 +open_dialog_name: + db 'opendial',0 +communication_area_default_path: + db '/rd/1/File managers/',0 + +Filter: +dd Filter.end - Filter ;.1 +.1: +db 'NC',0 +db 'PNG',0 +.end: +db 0 + + + +head_f_i: +head_f_l db 'Системная ошибка',0 + +system_dir_0 db '/sys/lib/' +lib_name_0 db 'proc_lib.obj',0 +err_message_found_lib_0 db 'Не найдена библиотека ',39,'proc_lib.obj',39,0 +err_message_import_0 db 'Ошибка при импорте библиотеки ',39,'proc_lib.obj',39,0 + +system_dir_1 db '/sys/lib/' +lib_name_1 db 'libimg.obj',0 +err_message_found_lib_1 db 'Не найдена библиотека ',39,'libimg.obj',39,0 +err_message_import_1 db 'Ошибка при импорте библиотеки ',39,'libimg.obj',39,0 + +system_dir_2 db '/sys/lib/' +lib_name_2 db 'buf2d.obj',0 +err_msg_found_lib_2 db 'Не найдена библиотека ',39,'buf2d.obj',39,0 +err_msg_import_2 db 'Ошибка при импорте библиотеки ',39,'buf2d',39,0 + +system_dir_3 db '/sys/lib/' +lib_name_3 db 'box_lib.obj',0 +err_msg_found_lib_3 db 'Не найдена библиотека ',39,'box_lib.obj',39,0 +err_msg_import_3 db 'Ошибка при импорте библиотеки ',39,'box_lib',39,0 + +l_libs_start: + lib_0 l_libs lib_name_0, sys_path, file_name, system_dir_0,\ + err_message_found_lib_0, head_f_l, proclib_import,err_message_import_0, head_f_i + lib_1 l_libs lib_name_1, sys_path, file_name, system_dir_1,\ + err_message_found_lib_1, head_f_l, import_libimg, err_message_import_1, head_f_i + lib_2 l_libs lib_name_2, sys_path, library_path, system_dir_2,\ + err_msg_found_lib_2,head_f_l,import_buf2d,err_msg_import_2,head_f_i + lib_3 l_libs lib_name_3, sys_path, file_name, system_dir_3,\ + err_msg_found_lib_3, head_f_l, import_box_lib,err_msg_import_3,head_f_i +l_libs_end: + +align 4 +import_libimg: + dd alib_init1 + img_is_img dd aimg_is_img + img_info dd aimg_info + img_from_file dd aimg_from_file + img_to_file dd aimg_to_file + img_from_rgb dd aimg_from_rgb + img_to_rgb dd aimg_to_rgb + img_to_rgb2 dd aimg_to_rgb2 + img_decode dd aimg_decode + img_encode dd aimg_encode + img_create dd aimg_create + img_destroy dd aimg_destroy + img_destroy_layer dd aimg_destroy_layer + img_count dd aimg_count + img_lock_bits dd aimg_lock_bits + img_unlock_bits dd aimg_unlock_bits + img_flip dd aimg_flip + img_flip_layer dd aimg_flip_layer + img_rotate dd aimg_rotate + img_rotate_layer dd aimg_rotate_layer + img_draw dd aimg_draw + + dd 0,0 + alib_init1 db 'lib_init',0 + aimg_is_img db 'img_is_img',0 ;определяет по данным, может ли библиотека сделать из них изображение + aimg_info db 'img_info',0 + aimg_from_file db 'img_from_file',0 + aimg_to_file db 'img_to_file',0 + aimg_from_rgb db 'img_from_rgb',0 + aimg_to_rgb db 'img_to_rgb',0 ;преобразование изображения в данные RGB + aimg_to_rgb2 db 'img_to_rgb2',0 + aimg_decode db 'img_decode',0 ;автоматически определяет формат графических данных + aimg_encode db 'img_encode',0 + aimg_create db 'img_create',0 + aimg_destroy db 'img_destroy',0 + aimg_destroy_layer db 'img_destroy_layer',0 + aimg_count db 'img_count',0 + aimg_lock_bits db 'img_lock_bits',0 + aimg_unlock_bits db 'img_unlock_bits',0 + aimg_flip db 'img_flip',0 + aimg_flip_layer db 'img_flip_layer',0 + aimg_rotate db 'img_rotate',0 + aimg_rotate_layer db 'img_rotate_layer',0 + aimg_draw db 'img_draw',0 + +align 4 +proclib_import: ;описание экспортируемых функций + OpenDialog_Init dd aOpenDialog_Init + OpenDialog_Start dd aOpenDialog_Start +dd 0,0 + aOpenDialog_Init db 'OpenDialog_init',0 + aOpenDialog_Start db 'OpenDialog_start',0 + +align 4 +import_buf2d: + init dd sz_init + buf2d_create dd sz_buf2d_create + buf2d_create_f_img dd sz_buf2d_create_f_img + buf2d_clear dd sz_buf2d_clear + buf2d_draw dd sz_buf2d_draw + buf2d_delete dd sz_buf2d_delete + buf2d_resize dd sz_buf2d_resize + buf2d_line dd sz_buf2d_line + buf2d_line_sm dd sz_buf2d_line_sm + buf2d_rect_by_size dd sz_buf2d_rect_by_size + buf2d_filled_rect_by_size dd sz_buf2d_filled_rect_by_size + buf2d_circle dd sz_buf2d_circle + buf2d_img_hdiv2 dd sz_buf2d_img_hdiv2 + buf2d_img_wdiv2 dd sz_buf2d_img_wdiv2 + buf2d_conv_24_to_8 dd sz_buf2d_conv_24_to_8 + buf2d_conv_24_to_32 dd sz_buf2d_conv_24_to_32 + buf2d_bit_blt dd sz_buf2d_bit_blt + buf2d_bit_blt_transp dd sz_buf2d_bit_blt_transp + buf2d_bit_blt_alpha dd sz_buf2d_bit_blt_alpha + buf2d_curve_bezier dd sz_buf2d_curve_bezier + buf2d_convert_text_matrix dd sz_buf2d_convert_text_matrix + buf2d_draw_text dd sz_buf2d_draw_text + buf2d_crop_color dd sz_buf2d_crop_color + buf2d_flip_h dd sz_buf2d_flip_h + buf2d_flip_v dd sz_buf2d_flip_v + buf2d_offset_h dd sz_buf2d_offset_h + buf2d_flood_fill dd sz_buf2d_flood_fill + buf2d_set_pixel dd sz_buf2d_set_pixel + dd 0,0 + sz_init db 'lib_init',0 + sz_buf2d_create db 'buf2d_create',0 + sz_buf2d_create_f_img db 'buf2d_create_f_img',0 + sz_buf2d_clear db 'buf2d_clear',0 + sz_buf2d_draw db 'buf2d_draw',0 + sz_buf2d_delete db 'buf2d_delete',0 + sz_buf2d_resize db 'buf2d_resize',0 + sz_buf2d_line db 'buf2d_line',0 + sz_buf2d_line_sm db 'buf2d_line_sm',0 + sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 + sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 + sz_buf2d_circle db 'buf2d_circle',0 + sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 + sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 + sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0 + sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0 + sz_buf2d_bit_blt db 'buf2d_bit_blt',0 + sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0 + sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0 + sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0 + sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0 + sz_buf2d_draw_text db 'buf2d_draw_text',0 + sz_buf2d_crop_color db 'buf2d_crop_color',0 + sz_buf2d_flip_h db 'buf2d_flip_h',0 + sz_buf2d_flip_v db 'buf2d_flip_v',0 + sz_buf2d_offset_h db 'buf2d_offset_h',0 + sz_buf2d_flood_fill db 'buf2d_flood_fill',0 + sz_buf2d_set_pixel db 'buf2d_set_pixel',0 + +align 4 +import_box_lib: + dd sz_init1 + + init_checkbox dd sz_Init_checkbox + check_box_draw dd sz_Check_box_draw + check_box_mouse dd sz_Check_box_mouse + ;version_ch dd sz_Version_ch + + option_box_draw dd sz_Option_box_draw + option_box_mouse dd sz_Option_box_mouse + ;version_op dd sz_Version_op + + edit_box_draw dd sz_edit_box_draw + edit_box_key dd sz_edit_box_key + edit_box_mouse dd sz_edit_box_mouse + edit_box_set_text dd sz_edit_box_set_text + scrollbar_ver_draw dd sz_scrollbar_ver_draw + scrollbar_hor_draw dd sz_scrollbar_hor_draw + + tl_data_init dd sz_tl_data_init + tl_data_clear dd sz_tl_data_clear + tl_info_clear dd sz_tl_info_clear + tl_key dd sz_tl_key + tl_mouse dd sz_tl_mouse + tl_draw dd sz_tl_draw + tl_info_undo dd sz_tl_info_undo + tl_info_redo dd sz_tl_info_redo + tl_node_add dd sz_tl_node_add + tl_node_set_data dd sz_tl_node_set_data + tl_node_get_data dd sz_tl_node_get_data + tl_node_delete dd sz_tl_node_delete + tl_node_move_up dd sz_tl_node_move_up + tl_node_move_down dd sz_tl_node_move_down + tl_cur_beg dd sz_tl_cur_beg + tl_cur_next dd sz_tl_cur_next + tl_cur_perv dd sz_tl_cur_perv + tl_node_close_open dd sz_tl_node_close_open + tl_node_lev_inc dd sz_tl_node_lev_inc + tl_node_lev_dec dd sz_tl_node_lev_dec + tl_node_poi_get_info dd sz_tl_node_poi_get_info + tl_node_poi_get_next_info dd sz_tl_node_poi_get_next_info + tl_node_poi_get_data dd sz_tl_node_poi_get_data + + dd 0,0 + sz_init1 db 'lib_init',0 + + sz_Init_checkbox db 'init_checkbox2',0 + sz_Check_box_draw db 'check_box_draw2',0 + sz_Check_box_mouse db 'check_box_mouse2',0 + ;sz_Version_ch db 'version_ch2',0 + + sz_Option_box_draw db 'option_box_draw',0 + sz_Option_box_mouse db 'option_box_mouse',0 + ;sz_Version_op db 'version_op',0 + + sz_edit_box_draw db 'edit_box',0 + sz_edit_box_key db 'edit_box_key',0 + sz_edit_box_mouse db 'edit_box_mouse',0 + sz_edit_box_set_text db 'edit_box_set_text',0 + sz_scrollbar_ver_draw db 'scrollbar_v_draw',0 + sz_scrollbar_hor_draw db 'scrollbar_h_draw',0 + + sz_tl_data_init db 'tl_data_init',0 + sz_tl_data_clear db 'tl_data_clear',0 + sz_tl_info_clear db 'tl_info_clear',0 + sz_tl_key db 'tl_key',0 + sz_tl_mouse db 'tl_mouse',0 + sz_tl_draw db 'tl_draw',0 + sz_tl_info_undo db 'tl_info_undo',0 + sz_tl_info_redo db 'tl_info_redo',0 + sz_tl_node_add db 'tl_node_add',0 + sz_tl_node_set_data db 'tl_node_set_data',0 + sz_tl_node_get_data db 'tl_node_get_data',0 + sz_tl_node_delete db 'tl_node_delete',0 + sz_tl_node_move_up db 'tl_node_move_up',0 + sz_tl_node_move_down db 'tl_node_move_down',0 + sz_tl_cur_beg db 'tl_cur_beg',0 + sz_tl_cur_next db 'tl_cur_next',0 + sz_tl_cur_perv db 'tl_cur_perv',0 + sz_tl_node_close_open db 'tl_node_close_open',0 + sz_tl_node_lev_inc db 'tl_node_lev_inc',0 + sz_tl_node_lev_dec db 'tl_node_lev_dec',0 + sz_tl_node_poi_get_info db 'tl_node_poi_get_info',0 + sz_tl_node_poi_get_next_info db 'tl_node_poi_get_next_info',0 + sz_tl_node_poi_get_data db 'tl_node_poi_get_data',0 + +align 4 +mouse_dd dd 0 +last_time dd 0 + +align 16 +sc system_colors + +align 16 +procinfo process_information + +align 4 +buf_0: dd 0 ;указатель на буфер изображения +.l: dw 205 ;+4 left +.t: dw 35 ;+6 top +.w: dd 384 ;+8 w +.h: dd 350 ;+12 h +.color: dd 0xffffd0 ;+16 color + db 24 ;+20 bit in pixel + +align 4 +buf_1: + dd 0 ;указатель на буфер изображения + dd 0 ;+4 left,top +.w: dd 0 +.h: dd 0,0,24 ;+12 color,bit in pixel + +font_h dd 0 ;высота шрифта + +align 4 +buf_png: + dd 0,0 +.w: dd 0 +.h: dd 0,0xffffff,24 + +align 4 +el_focus dd tree1 +tree1 tree_list size_one_list,1000+2, tl_key_no_edit+tl_draw_par_line,\ + 16,16, 0xffffff,0xb0d0ff,0x400040, 5,35,195-16,340, 16,Figure.Caption,0,\ + el_focus,w_scr_t1,0 + +align 4 +w_scr_t1 scrollbar 16,0, 3,0, 15, 100, 0,0, 0,0,0, 1 + +;input: +; eax - число +; edi - буфер для строки +; len - длинна буфера +;output: +align 4 +proc convert_int_to_str uses eax ecx edx edi esi, len:dword + mov esi,[len] + add esi,edi + dec esi + call .str + ret +endp + +align 4 +.str: + mov ecx,10 + cmp eax,ecx + jb @f + xor edx,edx + div ecx + push edx + ;dec edi ;смещение необходимое для записи с конца строки + call .str + pop eax + @@: + cmp edi,esi + jge @f + or al,0x30 + stosb + mov byte[edi],0 ;в конец строки ставим 0, что-бы не вылазил мусор + @@: + ret + +align 4 +proc mem_copy uses ecx esi edi, destination:dword, source:dword, len:dword + cld + mov esi, dword[source] + mov edi, dword[destination] + mov ecx, dword[len] + rep movsb + ret +endp + +align 16 +i_end: + rb 2048 +thread_coords: + rb 2048 +thread_scale: + rb 2048 +thread_n_file: + rb 2048 +stacktop: + sys_path rb 1024 + file_name: + rb 1024 ;4096 + library_path rb 1024 + plugin_path rb 4096 + openfile_path rb 4096 + filename_area rb 256 +mem: + diff --git a/programs/other/cnc_editor/cnc_editor.inc b/programs/other/cnc_editor/cnc_editor.inc new file mode 100644 index 0000000000..2b34648ed9 --- /dev/null +++ b/programs/other/cnc_editor/cnc_editor.inc @@ -0,0 +1,1728 @@ + +;FigureInit, (врем. стр.), (Object.FigData) + +;add_object_in_list, ___, ___, (врем. стр.), (Object.FigData) +; mov [Object.FigData], (tl_node_add(врем. стр.),tl_node_get_data) + +;draw_fig2d_litl, ___, pobj, (Object.FigData), ___, ___, ___ + +struct Object + OType dd ? + FigCount dd ? + FigData dd ? ;array pointers to Figures + MinX dq ? + MinY dq ? + SizeX dq ? + SizeY dq ? + WScale dq ? ;prewiew window scale + MScale dq ? ;mouse scale (show partition figure) + MCentrX dd ? ;mouse centr X + MCentrY dd ? ;mouse centr Y + Caption rb 32 +ends + +struct Figure + OType dd ? + PoiCount dd ? + PoiData dd ? + MinX dq ? + MinY dq ? + SizeX dq ? + SizeY dq ? + WScale dq ? ;prewiew window scale (show all figure) + MScale dq ? ;mouse scale (show partition figure) + MCentrX dd ? ;mouse centr X + MCentrY dd ? ;mouse centr Y + Caption rb 32 +ends + +struct Point + Prop dd ? ;prorerties + CoordX dq ? ;coord X + CoordY dq ? ;coord Y +ends + +txt_err_1 db 'Ошибка при считывании объекта',0 +txt_err_2 db 'Ошибка при считывании фигуры',0 +txt_err_3 db 'Не найдена точка в фигуре',0 +txt_err_no_figure_select db 'Не выбрана команда для перемещения',0 +txt_err_figure_is_0 db 'Команда не может быть сдвинута вверх,',13,10,'она в начале списка.',0 +txt_err_figure_is_last db 'Команда не может быть сдвинута вниз,',13,10,'она в конце списка.',0 +txt_err_no_point_del db 'Не можна удалить все точки из фигуры.',0 +txt_err_poi_is_0 db 'Не можна переместить точку вверх,',13,10,'она в начале списка.',0 +txt_err_poi_is_last db 'Не можна переместить точку вниз,',13,10,'она в конце списка.',0 +txt_err_no_1_point_sel db 'Выберите не больше одной точки.',0 + +txt_min_x db 'min x: ',0 +txt_min_y db 'min y: ',0 + +if lang eq ru +; +; rus +; +txt_err_no_point_sel db 'Не выбраны точки.',0 +txt_err_no_point_sel_1 db 'Выберите одну точку.',0 +txt_but_cancel db 'Отмена',0 +txt_but_apply db 'Применить',0 +txt_but_create db 'Создать',0 +txt_size_x db 'размер x: ',0 +txt_size_y db 'размер y: ',0 +txt_poi_sel: db 'Выбрано точек: ' +.end db 0 +txt_err_save_txt_file_0: + db 'Не могу сохранить *.nc файл.',0 +txt_err_save_txt_file_1: + db 'Не удалось сохранить весь *.nc файл.',0 +txt_err_save_img_file: + db 'Не могу сохранить *.png файл.',0 +txt_obj: db 'Объект: ',39 +.end db 0 +else +; +; eng +; +txt_err_no_point_sel db 'No select points.',0 +txt_err_no_point_sel_1 db 'Select one point.',0 +txt_but_cancel db 'Cancel',0 +txt_but_apply db 'Apply',0 +txt_but_create db 'Create',0 +txt_size_x db 'size x: ',0 +txt_size_y db 'size y: ',0 +txt_poi_sel: db 'Select points: ' +.end db 0 +txt_err_save_txt_file_0: +txt_err_save_txt_file_1: + db 'Can',39,'t save *.nc file.',0 +txt_err_save_img_file: + db 'Can',39,'t save *.png file.',0 +txt_obj: db 'Object: ',39 +.end db 0 +end if + +align 4 +txt_s_39 db 39,' ',0 +txt_s_poi db 'X',0 +txt_s_poi_Y db ' Y',0 +txt_s_poi_Z db ' Z',0 +txt_coma db ',' +txt_space db ' ',0 ;не отрывать от запятой +txt_nl db 13,10,0 +txt_n db 13,0 +txt_ls db ' (',0 +txt_rs db ')',0 +txt_len db ' len=',0 +txt_39 db 39,0 + +use_mem_array_figure equ 0 ;1 - использовать динамический массив для структур с описаниями фигур + +;свойства для рисования точек +PROP_BIT_SELECT equ 30 ;точка под выделением + +align 4 +zoom_plus dq 1.25992105 +mouse_prop_x dd 0 ;курсор мыши относительно центра окна buf_0 (для измен. масштаба) +mouse_prop_y dd 0 +mouse_down_x dd 0 ;курсор мыши относительно левого верхнего угла окна buf_0 (для сдвига фигуры) +mouse_down_y dd 0 +opt_draw dd 1 +graf_margin_left dd 3 ;margin in pixels +graf_margin_right dd 3+6 ;margin in pixels +graf_margin_top dd 3+9 ;margin in pixels +graf_margin_bot dd 3+9 ;margin in pixels +png_data dd ? +png_size dd ? + +;global variables: +ObjData Object +FigData Figure ;временная структура для заполнения tree1 +PoiData Point + +size_one_list equ sizeof.Figure ;max (sizeof.Figure, sizeof.Object) + +if sizeof.Object > sizeof.Figure + ... need fix size_one_list +end if + +if (Object.FigCount <> Figure.PoiCount) | (Object.FigData <> Figure.PoiData) | (Object.MScale <> Figure.MScale) | (Object.MCentrX <> Figure.MCentrX) | (Object.MCentrY <> Figure.MCentrY) + ... need fix offsets +end if + +align 4 +Scale1mm dq 11.81102362204724 ;pixels in 1 mm -> 300 dpi + ;5.905511811023622 ;pixels in 1 mm -> 150 dpi + +txt_buf rb 80 ;??? +txt_sp db ' ',0 + +;input: +; esi - text pointer +align 4 +proc txt_next_line uses eax ecx edi, mlen:dword + mov al,13 + mov ecx,[mlen] + mov edi,esi + repne scasb + cmp byte[edi],10 + jne @f + inc edi + @@: + mov esi,edi + ret +endp + +;input: +; edi - destination buffer +; esi - source text string: '...\nl +; mlen - maximum len destination buffer +align 4 +proc txt_load_line uses eax ebx ecx esi, mlen:dword + mov byte[edi],0 + mov al,13 + cmp byte[esi],al + je .end_f + mov ecx,[mlen] + mov ebx,edi + mov edi,esi + repne scasb ;found end of string + mov ecx,edi + sub ecx,esi + dec ecx ;ecx = string len + mov edi,ebx + rep movsb ;copy caption string + cmp byte[esi],13 + je @f + .cycle0: + inc esi + cmp byte[esi],13 + jne .cycle0 + @@: + mov byte[edi],0 + inc esi + .end_f: + ret +endp + +;input: +; itxt - input description text +; msize - max size +align 4 +proc FileInit uses eax ebx ecx edi esi, itxt:dword, msize:dword + stdcall [tl_node_poi_get_info], tree1,0 + or eax,eax + jz @f + mov ebx,eax + stdcall [tl_node_poi_get_data], tree1,ebx + stdcall clear_object_in_list, eax + @@: + stdcall [tl_info_clear], tree1 ;очистка списка объектов + mov dword[offs_last_timer],0 + + mov esi,[itxt] + mov ebx,esi + add ebx,[msize] + stdcall ObjectInit,ObjData,ebx + stdcall [tl_cur_beg], tree1 + ret +endp + +;input: +; esi - input description text +; pobj - pointer to object struct +; etxt - pointer to end of input text +align 4 +proc ObjectInit uses eax ebx ecx edi, pobj:dword, etxt:dword + mov ebx,[pobj] + mov [ebx+Object.OType],'Obj' + mov edi,ebx + add edi,Object.Caption + mov dword[edi],'CNC' + + stdcall get_max_lines + test eax,eax + jz .err_init + mov [ebx+Object.FigCount],eax + mov ecx,eax + + shl eax,2 + stdcall mem.Alloc,eax + mov [ebx+Object.FigData],eax + push ecx + mov edi,eax + xor eax,eax + rep stosd ;clear memory + pop ecx + + stdcall add_object_in_list,0,0,ebx,0 + ;eax -> pointer to object node + mov edi,[ebx+Object.FigData] +align 4 + .cycle0: + stdcall FigureInit,FigData,edi + cmp esi,[etxt] + jge .cycle0end + add edi,4 + loop .cycle0 + .cycle0end: + inc dword[ebx+Object.FigCount] ;??? + or ecx,ecx + jz @f + ;уменьшаем объем памяти выделенный для команд + sub [ebx+Object.FigCount],ecx + mov eax,[ebx+Object.FigCount] + shl eax,2 + stdcall mem.ReAlloc,[ebx+Object.FigData],eax + mov [ebx+Object.FigData],eax + @@: + + stdcall ObjCalculateScale,ebx + + jmp .end_f + .err_init: + notify_window_run txt_err_1 + .end_f: + ret +endp + +align 4 +proc ObjCalculateScale uses eax ebx ecx edi, pobj:dword + mov ebx,[pobj] + + ;*** Calculate scale for object *** + finit + + ;found min coord X + mov ecx,[ebx+Object.FigCount] + jecxz .cycle2end + mov edi,[ebx+Object.FigData] + push edi esi ;copy first min X + @@: + mov eax,[edi] + dec ecx + jecxz .cycle2end + add edi,4 + or eax,eax + jz @b + cmp [eax+Figure.PoiCount],0 + je @b + lea esi,[eax+Figure.MinX] + lea edi,[ebx+Object.MinX] + movsd + movsd + pop esi edi +align 4 + .cycle2: + mov eax,[edi] + or eax,eax + jz @f + cmp [eax+Figure.PoiCount],0 + je @f + fld qword[eax+Figure.MinX] + fcomp qword[ebx+Object.MinX] + fstsw ax + sahf + ja @f + push edi esi + mov eax,[edi] + lea esi,[eax+Figure.MinX] + lea edi,[ebx+Object.MinX] + movsd + movsd + pop esi edi + @@: + add edi,4 + loop .cycle2 + .cycle2end: + + ;found min coord Y + mov ecx,[ebx+Object.FigCount] + jecxz .cycle3end + mov edi,[ebx+Object.FigData] + push edi esi ;copy first min Y + @@: + mov eax,[edi] + dec ecx + jecxz .cycle3end + add edi,4 + or eax,eax + jz @b + cmp [eax+Figure.PoiCount],0 + je @b + lea esi,[eax+Figure.MinY] + lea edi,[ebx+Object.MinY] + movsd + movsd + pop esi edi +align 4 + .cycle3: + mov eax,[edi] + or eax,eax + jz @f + cmp [eax+Figure.PoiCount],0 + je @f + fld qword[eax+Figure.MinY] + fcomp qword[ebx+Object.MinY] + fstsw ax + sahf + ja @f + push edi esi + mov eax,[edi] + lea esi,[eax+Figure.MinY] + lea edi,[ebx+Object.MinY] + movsd + movsd + pop esi edi + @@: + add edi,4 + loop .cycle3 + .cycle3end: + + ;found max coord X + mov ecx,[ebx+Object.FigCount] + jecxz .cycle4end + mov edi,[ebx+Object.FigData] + ;copy first min X + mov eax,[edi] + fld qword[eax+Figure.MinX] + fadd qword[eax+Figure.SizeX] + fstp qword[ebx+Object.SizeX] + dec ecx + jecxz .cycle4end +align 4 + .cycle4: + add edi,4 + mov eax,[edi] + or eax,eax + jz @f + cmp [eax+Figure.PoiCount],0 + je @f + fld qword[eax+Figure.MinX] + fadd qword[eax+Figure.SizeX] + fcomp qword[ebx+Object.SizeX] + fstsw ax + sahf + jbe @f + mov eax,[edi] + fld qword[eax+Figure.MinX] + fadd qword[eax+Figure.SizeX] + fstp qword[ebx+Object.SizeX] + @@: + loop .cycle4 + .cycle4end: + + ;found max coord Y + mov ecx,[ebx+Object.FigCount] + jecxz .cycle5end + mov edi,[ebx+Object.FigData] + ;copy first min Y + mov eax,[edi] + fld qword[eax+Figure.MinY] + fadd qword[eax+Figure.SizeY] + fstp qword[ebx+Object.SizeY] + dec ecx + jecxz .cycle5end +align 4 + .cycle5: + add edi,4 + mov eax,[edi] + or eax,eax + jz @f + cmp [eax+Figure.PoiCount],0 + je @f + fld qword[eax+Figure.MinY] + fadd qword[eax+Figure.SizeY] + fcomp qword[ebx+Object.SizeY] + fstsw ax + sahf + jbe @f + mov eax,[edi] + fld qword[eax+Figure.MinY] + fadd qword[eax+Figure.SizeY] + fstp qword[ebx+Object.SizeY] + @@: + loop .cycle5 + .cycle5end: + + ;found size X + fld qword[ebx+Object.SizeX] + fsub qword[ebx+Object.MinX] + fstp qword[ebx+Object.SizeX] + ;found size Y + fld qword[ebx+Object.SizeY] + fsub qword[ebx+Object.MinY] + fstp qword[ebx+Object.SizeY] + + ;*** Calculate scale *** + fld1 + fstp qword[ebx+Object.WScale] ;set default scale + + fld qword[ebx+Object.SizeX] + ftst + fstsw ax + sahf + jne .els_0 ;if (SizeX == 0.0) + ffree st0 + fincstp + jmp .els_1 + .els_0: ;else if (SizeX != 0.0) + fild dword[buf_0.w] + fisub dword[graf_margin_left] + fisub dword[graf_margin_right] + fxch st1 + fdivp + fstp qword[ebx+Object.WScale] + .els_1: + + fld qword[ebx+Object.SizeY] + ftst + fstsw ax + sahf + jne .els_2 ;if (SizeY == 0.0) + ffree st0 + fincstp + jmp .els_3 + .els_2: ;else if (SizeY != 0.0) + fild dword[buf_0.h] + fisub dword[graf_margin_top] + fisub dword[graf_margin_bot] + fxch st1 + fdivp + fcom qword[ebx+Object.WScale] + fstsw ax + sahf + jbe @f + ffree st0 + fincstp + jmp .els_3 + @@: + fstp qword[ebx+Object.WScale] + .els_3: + + fld1 + fstp qword[ebx+Figure.MScale] + mov dword[ebx+Figure.MCentrX],0 + mov dword[ebx+Figure.MCentrY],0 + ret +endp + +;input: +; esi - input description text +; pmem - pointer to memory for struct +; pfig - pointer to figure struct +;output: +; esi - output description text +align 4 +proc FigureInit uses eax ebx ecx edx edi, pmem:dword, pfig:dword + mov ebx,[pmem] + mov [ebx+Figure.OType],'Fig' + mov edi,ebx + add edi,Figure.Caption + stdcall txt_load_line,32 + + xor eax,eax + mov [ebx+Figure.PoiCount],eax + mov [ebx+Figure.PoiData],eax + cmp byte[esi],'X' + jne .end0 + stdcall get_max_points + mov [ebx+Figure.PoiCount],eax + or eax,eax + jz .end0 + mov ecx,eax + imul eax,sizeof.Point + stdcall mem.Alloc,eax + mov [ebx+Figure.PoiData],eax + or eax,eax + jz .err_init + mov edi,eax +align 4 + .cycle0: + stdcall PointInit,edi + or eax,eax + jz .cycle0end + add edi,sizeof.Point + loop .cycle0 + .cycle0end: + or ecx,ecx + jz .end1 + ;уменьшаем объем памяти выделенный для точек + sub [ebx+Figure.PoiCount],ecx + mov eax,[ebx+Figure.PoiCount] + imul eax,sizeof.Point + stdcall mem.ReAlloc,[ebx+Figure.PoiData],eax + mov [ebx+Figure.PoiData],eax + jmp .end1 + .err_init: + notify_window_run txt_err_2 + .end0: + ;command + stdcall txt_next_line, 80 + cmp byte[esi],13 + jne @f + ;if null line + inc esi + cmp byte[esi],10 + jne .end2 + inc esi + .end2: + mov dword[edi],(10 shl 8)+13 ;new line + @@: + stdcall add_object_in_list,1,1,ebx,[pfig] + jmp .end_f + .end1: + ;coords + stdcall add_object_in_list,2,1,ebx,[pfig] + or eax,eax + jz .end_f + stdcall FigCalculateSizes,eax,1 + .end_f: + ret +endp + +;input: +; esi - pointer to file +;output: +; eax - max lines in file +align 4 +proc get_max_lines uses esi + xor eax,eax + .cycle0: + cmp byte[esi],13 + jne @f + inc eax + @@: + inc esi + cmp byte[esi],0 + jne .cycle0 + ret +endp + +;input: +; esi - pointer to file +;output: +; eax - max point coords in file +align 4 +proc get_max_points uses esi + xor eax,eax + .cycle0: + cmp word[esi],' Y' + jne @f + inc eax + @@: + inc esi + cmp byte[esi+1],0 + jne .cycle0 + ret +endp + +;input: +; opt_calc - если 0 - пересчитать масштаб фигуры, +; 1 - пересчитать размеры и масштаб фигуры +align 4 +proc FigCalculateSizes uses eax ebx ecx edi esi, pfig:dword, opt_calc:dword + mov ebx,[pfig] + or ebx,ebx + jz .end_f + + finit + bt dword[opt_calc],0 + jnc .calc_scale + + ;*** Calculate sizes *** + mov esi,[ebx+Figure.PoiData] + or esi,esi + jz .end_f + + lea esi,[esi+Point.CoordX] + lea edi,[ebx+Figure.MinX] + movsd + movsd ;Figure.MinX = Point[0].CoordX + sub esi,8 + lea edi,[ebx+Figure.SizeX] + movsd + movsd ;Figure.SizeX = Point[0].CoordX + mov esi,[ebx+Figure.PoiData] + lea esi,[esi+Point.CoordY] + lea edi,[ebx+Figure.MinY] + movsd + movsd ;Figure.MinY = Point[0].CoordY + sub esi,8 + lea edi,[ebx+Figure.SizeY] + movsd + movsd ;Figure.SizeY = Point[0].CoordY + + ;found min coord X + mov ecx,[ebx+Figure.PoiCount] + jecxz .cycle2end + mov edi,[ebx+Figure.PoiData] +align 4 + .cycle2: + fld qword[edi+Point.CoordX] + fcomp qword[ebx+Figure.MinX] + fstsw ax + sahf + ja @f + push edi esi + lea esi,[edi+Point.CoordX] + lea edi,[ebx+Figure.MinX] + movsd + movsd + pop esi edi + @@: + add edi,sizeof.Point + loop .cycle2 + .cycle2end: + + ;found min coord Y + mov ecx,[ebx+Figure.PoiCount] + jecxz .cycle3end + mov edi,[ebx+Figure.PoiData] +align 4 + .cycle3: + fld qword[edi+Point.CoordY] + fcomp qword[ebx+Figure.MinY] + fstsw ax + sahf + ja @f + push edi esi + lea esi,[edi+Point.CoordY] + lea edi,[ebx+Figure.MinY] + movsd + movsd + pop esi edi + @@: + add edi,sizeof.Point + loop .cycle3 + .cycle3end: + + ;found max coord X + mov ecx,[ebx+Figure.PoiCount] + jecxz .cycle4end + mov edi,[ebx+Figure.PoiData] +align 4 + .cycle4: + fld qword[edi+Point.CoordX] + fcomp qword[ebx+Figure.SizeX] + fstsw ax + sahf + jbe @f + push edi esi + lea esi,[edi+Point.CoordX] + lea edi,[ebx+Figure.SizeX] + movsd + movsd + pop esi edi + @@: + add edi,sizeof.Point + loop .cycle4 + .cycle4end: + + ;found max coord Y + mov ecx,[ebx+Figure.PoiCount] + jecxz .cycle5end + mov edi,[ebx+Figure.PoiData] +align 4 + .cycle5: + fld qword[edi+Point.CoordY] + fcomp qword[ebx+Figure.SizeY] + fstsw ax + sahf + jbe @f + push edi esi + lea esi,[edi+Point.CoordY] + lea edi,[ebx+Figure.SizeY] + movsd + movsd + pop esi edi + @@: + add edi,sizeof.Point + loop .cycle5 + .cycle5end: + + ;found size X + fld qword[ebx+Figure.SizeX] + fsub qword[ebx+Figure.MinX] + fstp qword[ebx+Figure.SizeX] + ;found size Y + fld qword[ebx+Figure.SizeY] + fsub qword[ebx+Figure.MinY] + fstp qword[ebx+Figure.SizeY] + + ;*** Calculate scale *** +align 4 + .calc_scale: + mov dword[ebx+Figure.MCentrX],0 + mov dword[ebx+Figure.MCentrY],0 + fld1 + fst qword[ebx+Figure.MScale] ;??? + fstp qword[ebx+Figure.WScale] ;set default scale + + fld qword[ebx+Figure.SizeX] + ftst + fstsw ax + sahf + jne .els_0 ;if (SizeX == 0.0) + ffree st0 + fincstp + jmp .els_1 + .els_0: ;else if (SizeX != 0.0) + fild dword[buf_0.w] + fisub dword[graf_margin_left] + fisub dword[graf_margin_right] + fxch st1 + fdivp + fstp qword[ebx+Figure.WScale] + .els_1: + + fld qword[ebx+Figure.SizeY] + ftst + fstsw ax + sahf + jne .els_2 ;if (SizeY == 0.0) + ffree st0 + fincstp + jmp .els_3 + .els_2: ;else if (SizeY != 0.0) + fild dword[buf_0.h] + fisub dword[graf_margin_top] + fisub dword[graf_margin_bot] + fxch st1 + fdivp + fcom qword[ebx+Figure.WScale] + fstsw ax + sahf + jbe @f + ffree st0 + fincstp + jmp .els_3 + @@: + fstp qword[ebx+Figure.WScale] + .els_3: + + .end_f: + ret +endp + +;input: +; esi - input description text +; ppoi - pointer to point struct +;output: +; eax - 0 (if error init) or 1 +; esi - output description text +align 4 +proc PointInit uses ebx ecx edi, ppoi:dword + mov ecx,64 ;защита от зацикливания + @@: + lodsb + cmp al,' ' + jne @f + loop @b + @@: + dec esi + cmp byte[esi],'X' + jne .err_init + inc esi + stdcall conv_str_to_int, esi + mov ebx,[ppoi] + + ;Data_String <- esi + push esi + mov ecx,32 + mov edi,esi + @@: + lodsb + or al,al + jz @f + cmp al,' ' + je @f + cmp al,13 + je @f + loop @b + @@: + mov esi,edi + sub ecx,32 + neg ecx + mov edi,Data_String + rep movsb + mov byte[edi],0 + pop esi + stdcall String_to_DoubleFloat + ;Data_Double -> Point.CoordX + push esi + mov esi,Data_Double + lea edi,[ebx+Point.CoordX] + movsd + movsd + pop esi + + push edi + mov al,'Y' + mov ecx,80 + mov edi,esi + repne scasb + mov esi,edi + pop edi + ;Data_String <- esi + push esi + mov ecx,32 + mov edi,esi + @@: + lodsb + or al,al + jz @f + cmp al,' ' + je @f + cmp al,13 + je @f + loop @b + @@: + mov esi,edi + sub ecx,32 + neg ecx + mov edi,Data_String + rep movsb + mov byte[edi],0 + pop esi + stdcall String_to_DoubleFloat + ;Data_Double -> Point.CoordY + push esi + mov esi,Data_Double + lea edi,[ebx+Point.CoordY] + movsd + movsd + pop esi + + stdcall txt_next_line, 80 + jmp @f + .err_init: + xor eax,eax + jmp .end_f + @@: + xor eax,eax + inc eax + .end_f: + ret +endp + +;input: +; icon - номер иконки +; level - уровень вложенности узла +; buffer - добавляемые данные +; pfig - указатель на добавленную фигуру (для контроля со стороны родительского объекта) +;output: +; eax - object data pointer +align 4 +proc add_object_in_list uses ebx, icon:dword,level:dword,buffer:dword, pfig:dword + mov ax,word[icon] + shl eax,16 + mov ax,word[level] + + stdcall [tl_node_add], tree1, eax, [buffer] + stdcall [tl_node_get_data],tree1 + mov ebx,[pfig] + or ebx,ebx + jz @f + mov [ebx],eax + @@: + stdcall [tl_cur_next], tree1 + ret +endp + +align 4 +proc clear_object_in_list uses eax, buffer:dword + mov eax,[buffer] + cmp dword[eax+Object.FigCount],0 ;or Figure.PoiCount + je .end_f + stdcall mem.Free,[eax+Object.FigData] ;or Figure.PoiData + .end_f: + ret +endp + +;description: +; функция для рисования выбранного объекта +align 4 +proc draw_obj2d, pobj:dword +locals + CentrX dd ? + CentrY dd ? +endl +pushad + mov ebx,[pobj] + stdcall [buf2d_clear], buf_0, [buf_0.color] + mov ecx,[ebx+Object.FigCount] + or ecx,ecx + jz .end_f + ;;jecxz .end_f + mov edi,[ebx+Object.FigData] + finit + fld qword[ebx+Object.SizeY] + fmul qword[ebx+Object.WScale] + fmul qword[ebx+Object.MScale] + fchs + fistp dword[CentrY] + mov eax,[CentrY] + sub eax,[graf_margin_top] + sub eax,[graf_margin_bot] + add eax,[buf_0.h] + sar eax,1 + add eax,[graf_margin_bot] ;_bot а не _top - в связи с тем что коорд. Y перевернута + add eax,[ebx+Object.MCentrY] + mov [CentrY],eax + fld qword[ebx+Object.SizeX] + fmul qword[ebx+Object.WScale] + fmul qword[ebx+Object.MScale] + fchs + fistp dword[CentrX] + mov edx,[CentrX] + sub edx,[graf_margin_left] + sub edx,[graf_margin_right] + add edx,[buf_0.w] + sar edx,1 + add edx,[graf_margin_left] + add edx,[ebx+Object.MCentrX] + mov [CentrX],edx +align 4 + .cycle0: + stdcall draw_fig2d_litl, buf_0,ebx,[edi],0,edx,eax + add edi,4 + loop .cycle0 + stdcall [buf2d_flip_v], buf_0 + + bt dword[opt_draw],0 + jnc .end_f + ; draw min & sizes + mov word[NumberSymbolsAD],8 + stdcall mem_copy, txt_buf,txt_size_x,20 + fld qword[ebx+Object.SizeX] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall str_cat,txt_buf,txt_n + stdcall str_cat,txt_buf,txt_size_y + fld qword[ebx+Object.SizeY] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall [buf2d_draw_text], buf_0, buf_1,txt_buf,3,23,0 + + fld qword[ebx+Object.MinX] + fstp qword[Data_Double] + stdcall mem_copy, txt_buf,txt_min_x,20 + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall str_cat,txt_buf,txt_n + stdcall str_cat,txt_buf,txt_min_y + fld qword[ebx+Object.MinY] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall [buf2d_draw_text], buf_0, buf_1,txt_buf,3,3,0 + .end_f: +popad + ret +endp + +align 4 +proc draw_obj2d_png uses eax ebx ecx edi esi, pobj:dword + mov ebx,[pobj] + mov ecx,[ebx+Object.FigCount] + cmp dword[ebx+Object.FigCount],0 + or ecx,ecx + jz .end_f + ;;jecxz .end_f + mov edi,[ebx+Object.FigData] + stdcall [buf2d_delete], buf_png + finit + fld qword[ebx+Object.SizeY] + fmul qword[Scale1mm] + fiadd dword[graf_margin_top] + fiadd dword[graf_margin_bot] + fistp dword[buf_png.h] + fld qword[ebx+Object.SizeX] + fmul qword[Scale1mm] + fiadd dword[graf_margin_left] + fiadd dword[graf_margin_right] + fistp dword[buf_png.w] + stdcall [buf2d_create], buf_png +align 4 + .cycle0: + stdcall draw_fig2d_litl, buf_png,ebx,[edi],Scale1mm,[graf_margin_left],[graf_margin_bot] ;_bot а не _top - в связи с тем что коорд. Y перевернута + add edi,4 + loop .cycle0 + stdcall [buf2d_flip_v], buf_png + .end_f: + ret +endp + +;input: +; pbuf - pointer to buffer 2d +;description: +; функция для рисования объекта по частям +align 4 +proc draw_fig2d_litl, pbuf:dword, pobj:dword, pfig:dword, Scale:dword, CentrX:dword, CentrY:dword +locals + PervX dd 0 ;pervios point coord X + PervY dd 0 ;pervios point coord Y + GrafX dd ? ;active point coord X + GrafY dd ? ;active point coord Y +endl +pushad + mov ebx,[pfig] + test ebx,ebx + jz .end_f + mov ecx,[ebx+Figure.PoiCount] + ;;jecxz .end_f + test ecx,ecx + jz .end_f + mov edi,[ebx+Figure.PoiData] + mov edx,[pobj] + + fld1 + mov eax,[Scale] + or eax,eax + jnz @f + lea eax,[edx+Object.MScale] + fmul qword[eax] + lea eax,[edx+Object.WScale] + @@: + fmul qword[eax] +align 4 + .cycle0: + fld qword[edi+Point.CoordX] + fsub qword[edx+Object.MinX] + fmul st0,st1 + fiadd dword[CentrX] + fistp dword[ebp-8] + fld qword[edi+Point.CoordY] + fsub qword[edx+Object.MinY] + fmul st0,st1 + fiadd dword[CentrY] + fistp dword[ebp-4] + stdcall [buf2d_set_pixel], [pbuf], [GrafX],[GrafY], 0xff0000 + cmp ecx,[ebx+Figure.PoiCount] + je @f + stdcall [buf2d_line_sm], [pbuf], [PervX],[PervY], [GrafX],[GrafY], 0x80 + ;sub esp,24 + ;call [buf2d_line] + stdcall [buf2d_line], [pbuf], [PervX],[PervY], [GrafX],[GrafY], 0x80 + @@: + mov eax,[GrafX] + mov [PervX],eax + mov eax,[GrafY] + mov [PervY],eax + add edi,sizeof.Point + ;;loop .cycle0 + dec ecx + jnz .cycle0 + ffree st0 + fincstp + + .end_f: +popad + ret +endp + +;description: +; функция для рисования выбранной фигуры +align 4 +proc draw_fig2d, pfig:dword +locals + n dd 0 + col_lin dd 0 ;цвет линий фигуры + CentrX dd ? + CentrY dd ? + PervX dd 0 ;pervios point coord X + PervY dd 0 ;pervios point coord Y + GrafX dd ? ;active point coord X + GrafY dd ? ;active point coord Y + old_tl dd 0 ;old text coord X0 + old_tt dd 0 ;old text coord Y0 + old_tw dd 0 ;old text coord X1 + old_th dd 0 ;old text coord Y1 + new_tl dd 0 ;new text coord X0 + ;new_tt dd 0 ;new text coord Y0 + new_tw dd 0 ;new text coord X1 + ;new_th dd 0 ;new text coord Y1 +endl +pushad + stdcall [buf2d_clear], buf_0, [buf_0.color] + mov ebx,[pfig] + test ebx,ebx + jz .end_f + mov ecx,[ebx+Figure.PoiCount] + ;;jecxz .end_f + test ecx,ecx + jz .end_f + mov edi,[ebx+Figure.PoiData] + finit + fld qword[ebx+Figure.SizeY] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fchs + fistp dword[CentrY] + mov eax,[CentrY] + sub eax,[graf_margin_top] + sub eax,[graf_margin_bot] + add eax,[buf_0.h] + sar eax,1 + add eax,[graf_margin_bot] + add eax,[ebx+Figure.MCentrY] + mov [CentrY],eax + ;CentrY = (-(Figure.SizeY * Figure.WScale) - graf_margin_top - graf_margin_bot + buf_0.h) / 2 + graf_margin_bot + fld qword[ebx+Figure.SizeX] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fchs + fistp dword[CentrX] + mov eax,[CentrX] + sub eax,[graf_margin_left] + sub eax,[graf_margin_right] + add eax,[buf_0.w] + sar eax,1 + add eax,[graf_margin_left] + add eax,[ebx+Figure.MCentrX] + mov [CentrX],eax + ;CentrX = (-(Figure.SizeX * Figure.WScale) - graf_margin_left - graf_margin_right + buf_0.w) / 2 + graf_margin_left + +align 4 + .cycle0: + fld qword[edi+Point.CoordX] + fsub qword[ebx+Figure.MinX] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fiadd dword[CentrX] + fistp dword[GrafX] + ;GrafX = (Point.CoordX - Figure.MinX) * Figure.WScale + CentrX + fld qword[edi+Point.CoordY] + fsub qword[ebx+Figure.MinY] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fiadd dword[CentrY] + fisub dword[buf_0.h] ;invert coord Y + fchs + fistp dword[GrafY] + ;GrafY = -((Point.CoordY - Figure.MinY) * Figure.WScale + CentrY - buf_0.h) + + stdcall [buf2d_set_pixel], buf_0, [GrafX],[GrafY], 0xff0000 + mov dword[col_lin],0x80 + bt dword[edi+Point.Prop],PROP_BIT_SELECT + jnc @f + stdcall [buf2d_circle], buf_0, [GrafX],[GrafY], 3, 0xff0000 + @@: + cmp ecx,[ebx+Figure.PoiCount] + je @f + stdcall [buf2d_line_sm], buf_0, [PervX],[PervY], [GrafX],[GrafY], [col_lin] + stdcall [buf2d_line], buf_0, [PervX],[PervY], [GrafX],[GrafY], [col_lin] + @@: + mov eax,[GrafX] + mov [PervX],eax + mov edx,[GrafY] + mov [PervY],edx + add edi,sizeof.Point + + bt dword[opt_draw],0 + jnc .end0 + ; draw number points + ;mov eax,[GrafX] + ;mov edx,[GrafY] + add eax,2 + add edx,2 + push eax edi + mov eax,[n] + mov edi,txt_buf + stdcall convert_int_to_str,20 + pop edi eax + + inc dword[n] + ;calculate new text coords + mov [new_tl],eax + mov esi,eax + stdcall str_len,txt_buf + imul eax,[buf_1.w] + add eax,esi + mov [new_tw],eax + ;rect compare coords + cmp [old_tl],eax + jg .no_comp + cmp [old_tw],esi + jl .no_comp + ;calculate new text coord Y1 + mov esi,edx + add esi,[font_h] + cmp [old_tt],esi + jg .no_comp + cmp [old_th],edx + ;jl .no_comp + ;jmp .end0 + jge .end0 + .no_comp: + mov eax,[new_tl] + mov [old_tl],eax + mov eax,[new_tw] + mov [old_tw],eax + mov [old_tt],edx + add edx,[font_h] + mov [old_th],edx + stdcall [buf2d_draw_text], buf_0, buf_1,txt_buf,[old_tl],[old_tt],0x000000 + .end0: + dec ecx + jnz .cycle0 + + stdcall sel_points_get_count,[pfig] + or eax,eax + jz .no_point + stdcall mem_copy, txt_buf,txt_poi_sel,txt_poi_sel.end-txt_poi_sel + mov edi,txt_buf+txt_poi_sel.end-txt_poi_sel + stdcall convert_int_to_str, 20 + mov word[NumberSymbolsAD],8 + cmp eax,1 + jne @f + ;если выбрана одна точка, то по ней вывод более детальной информации + stdcall sel_points_get_first,[pfig] + stdcall str_cat,txt_buf,txt_ls + fld qword[eax+Point.CoordX] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall str_cat,txt_buf,txt_coma + fld qword[eax+Point.CoordY] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall str_cat,txt_buf,txt_rs + jmp .end1 + @@: + cmp eax,2 + jne .end1 + ;если выбрано 2 точки + stdcall sel_points_get_first,[pfig] + fld qword[eax+Point.CoordX] + fld qword[eax+Point.CoordY] + stdcall sel_points_get_last,[pfig] + fsub qword[eax+Point.CoordY] + fmul st0,st0 + fxch st1 + fsub qword[eax+Point.CoordX] + fmul st0,st0 + faddp st1,st0 + fsqrt + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,txt_len + stdcall str_cat,txt_buf,Data_String + .end1: + stdcall [buf2d_draw_text], buf_0, buf_1,txt_buf,3,3,0 + jmp .end_f ;не выводим информацию о размерах + .no_point: + + bt dword[opt_draw],0 + jnc .end_f + ; draw min & sizes + mov word[NumberSymbolsAD],8 + stdcall mem_copy, txt_buf,txt_size_x,20 + fld qword[ebx+Figure.SizeX] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall str_cat,txt_buf,txt_n + stdcall str_cat,txt_buf,txt_size_y + fld qword[ebx+Figure.SizeY] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall [buf2d_draw_text], buf_0, buf_1,txt_buf,3,23,0 + + fld qword[ebx+Figure.MinX] + fstp qword[Data_Double] + stdcall mem_copy, txt_buf,txt_min_x,20 + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall str_cat,txt_buf,txt_n + stdcall str_cat,txt_buf,txt_min_y + fld qword[ebx+Figure.MinY] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall str_cat,txt_buf,Data_String + stdcall [buf2d_draw_text], buf_0, buf_1,txt_buf,3,3,0 + .end_f: +popad + ret +endp + +;input: +; pnode - указатель на данные узла +align 4 +proc get_object_data, pnode:dword + mov ecx,[pnode] + cmp [ecx+Object.OType],'Obj' + jne .end0 + mov ecx,ObjData + jmp .end_f + .end0: + xor ecx,ecx + .end_f: + ret +endp + +;input: +; pfig - pointer to figure +;output: +; eax - указатель на родительский объект или 0 если не найдено +; ecx - номер фигуры внутри объекта +align 4 +proc found_parent_obj uses ebx edx edi, pfig:dword + mov eax,ObjData + mov edx,[eax+Object.FigCount] + or edx,edx + jz .cycle1end + mov edi,[eax+Object.FigData] + xor ecx,ecx + .cycle1: ;цикл по фигурам + mov ebx,[edi] + cmp ebx,[pfig] + je .end_f ;если найдено + add edi,4 + inc ecx + dec edx + jnz .cycle1 + .cycle1end: + xor eax,eax + .end_f: + ret +endp + +;description: +; считает колличество выделенных точек +align 4 +proc sel_points_get_count uses ebx ecx, pFig:dword + xor eax,eax + mov ebx,[pFig] + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov ebx,[ebx+Figure.PoiData] + .cycle0: + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc @f + inc eax + @@: + add ebx,sizeof.Point + loop .cycle0 + .no_point: + ret +endp + +;description: +; берет указатель на первую выделенную точку +;output: +; eax - указатель на точку или 0 если не выделенно +align 4 +proc sel_points_get_first uses ecx, pFig:dword + mov eax,[pFig] + mov ecx,[eax+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov eax,[eax+Figure.PoiData] + .cycle0: + bt dword[eax+Point.Prop],PROP_BIT_SELECT + jc .end_f + add eax,sizeof.Point + loop .cycle0 + .no_point: + xor eax,eax + .end_f: + ret +endp + +;input: +; pObj - указатель на объект +; FigN - номер комманды +;description: +; пересчет фигур после обновления координат точки +align 4 +proc figure_update_coords uses eax ecx edx, pObj:dword, FigN:dword + mov eax,[pObj] + mov ecx,[eax+Object.FigCount] + mov eax,[eax+Object.FigData] + mov edx,[FigN] + cmp ecx,edx + jle @f + stdcall FigCalculateSizes,[eax+4*edx],1 + stdcall ObjCalculateScale,[pObj] + @@: + ret +endp + +;description: +; берет указатель на последнюю выделенную точку +align 4 +proc sel_points_get_last uses ebx ecx, pFig:dword + mov ebx,[pFig] + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov eax,ecx + dec eax + imul eax,sizeof.Point + add eax,[ebx+Figure.PoiData] + .cycle0: + bt dword[eax+Point.Prop],PROP_BIT_SELECT + jc .end_f + sub eax,sizeof.Point + loop .cycle0 + .no_point: + xor eax,eax + .end_f: + ret +endp + +;description: +; снимает выделение с точек +align 4 +proc sel_points_clear uses ebx ecx, pFig:dword + mov ebx,[pFig] + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov ebx,[ebx+Figure.PoiData] + .cycle0: + btr dword[ebx+Point.Prop],PROP_BIT_SELECT + add ebx,sizeof.Point + loop .cycle0 + .no_point: + ret +endp + +;description: +; инвертирует указанный бит в свойствах выделенных точек +align 4 +proc sel_points_invert_bit uses eax ebx ecx, pFig:dword, iBit:dword + mov ecx,[iBit] + xor eax,eax + inc eax + shl eax,cl + mov ebx,[pFig] + mov ecx,[ebx+Figure.PoiCount] + or ecx,ecx + jz .no_point + mov ebx,[ebx+Figure.PoiData] + .cycle0: + bt dword[ebx+Point.Prop],PROP_BIT_SELECT + jnc @f + xor dword[ebx+Point.Prop],eax + @@: + add ebx,sizeof.Point + loop .cycle0 + .no_point: + ret +endp + +;input: +; pPoi - указатель на данные точки +align 4 +proc point_move_up, pObj:dword,pFig:dword,idFig:dword,pPoi:dword +pushad + ;изменение ссылок на точки + mov eax,[pObj] + mov ecx,[idFig] + mov edx,[eax+Object.FigCount] + or edx,edx + jz .end_f + mov edi,[eax+Object.FigData] + + ;меняем точки местами + mov ecx,sizeof.Point + mov esi,[pPoi] + sub esi,ecx + mov edi,PoiData + rep movsb ;p(-1) > p_s + mov ecx,sizeof.Point + mov edi,[pPoi] + sub edi,ecx + rep movsb ;p(0) > p(-1) + mov esi,PoiData + mov ecx,sizeof.Point + rep movsb ;p_s > p(0) + .end_f: +popad + ret +endp + +align 4 +proc mouse_left_d uses eax ebx + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_f + + cmp [eax+Figure.OType],'Fig' + je @f + cmp [eax+Figure.OType],'Obj' + je .end0 + jmp .end_f + .end0: + mov eax,ObjData + @@: + call buf_get_mouse_coord + cmp eax,-1 + je .end_f + mov [mouse_down_x],eax + mov [mouse_down_y],ebx + .end_f: + ret +endp + +align 4 +proc mouse_left_u uses eax ebx ecx + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_f + + cmp [eax+Figure.OType],'Fig' + je @f + cmp [eax+Figure.OType],'Obj' + je .end0 + jmp .end_f + .end0: + mov eax,ObjData + @@: + mov ecx,eax + + call buf_get_mouse_coord + cmp eax,-1 + je .end_f + sub eax,[mouse_down_x] + sub ebx,[mouse_down_y] + add [ecx+Figure.MCentrX],eax + sub [ecx+Figure.MCentrY],ebx + mov dword[offs_last_timer],0 + .end_f: + ret +endp + +;output: +; eax, ebx - портятся +align 4 +proc mouse_right_d uses ecx edx edi +locals + BufX dd ? + BufY dd ? + CentrX dd ? + CentrY dd ? + GrafX dd ? ;active point coord X + GrafY dd ? ;active point coord Y +endl + call buf_get_mouse_coord + cmp eax,-1 + je .end_f + mov [BufX],eax + mov [BufY],ebx + + ;просматриваем выделенный блок данных + stdcall [tl_node_get_data],tree1 + or eax,eax + jz .end_f + + cmp [eax+Figure.OType],'Fig' + jne .end_fblo + + mov ecx,eax + mcall SF_KEYBOARD,SSF_GET_CONTROL_KEYS ;проверка Shift + bt eax,0 + jc @f + bt eax,1 + jc @f + ;если не нажат Shift + stdcall sel_points_clear,ecx + @@: + mov ebx,ecx + mov ecx,[ebx+Figure.PoiCount] + ;;jecxz .end_f + test ecx,ecx + jz .end_f + + mov edi,[ebx+Figure.PoiData] + finit + fld qword[ebx+Figure.SizeY] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fchs + fistp dword[CentrY] + mov eax,[CentrY] + sub eax,[graf_margin_top] + sub eax,[graf_margin_bot] + add eax,[buf_0.h] + sar eax,1 + add eax,[graf_margin_bot] + add eax,[ebx+Figure.MCentrY] + mov [CentrY],eax + fld qword[ebx+Figure.SizeX] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fchs + fistp dword[CentrX] + mov eax,[CentrX] + sub eax,[graf_margin_left] + sub eax,[graf_margin_right] + add eax,[buf_0.w] + sar eax,1 + add eax,[graf_margin_left] + add eax,[ebx+Figure.MCentrX] + mov [CentrX],eax + +align 4 + .cycle0: + fld qword[edi+Point.CoordX] + fsub qword[ebx+Figure.MinX] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fiadd dword[CentrX] + fistp dword[GrafX] + fld qword[edi+Point.CoordY] + fsub qword[ebx+Figure.MinY] + fmul qword[ebx+Figure.WScale] + fmul qword[ebx+Figure.MScale] + fiadd dword[CentrY] + fisub dword[buf_0.h] ;invert coord Y + fchs + fistp dword[GrafY] + + mov eax,[GrafX] + sub eax,[BufX] + bt eax,31 + jnc @f + neg eax + @@: + mov edx,[GrafY] + sub edx,[BufY] + bt edx,31 + jnc @f + neg edx + @@: + add eax,edx + cmp eax,7 ;приблизительное расстояние до точки + jg @f + ;выделяем или снимаем выделение с точек + xor dword[edi+Point.Prop],(1 shl PROP_BIT_SELECT) + @@: + + add edi,sizeof.Point + dec ecx + jnz .cycle0 + + mov dword[offs_last_timer],0 + ;jmp .end_f + .end_fblo: + + .end_f: + ret +endp diff --git a/programs/other/cnc_editor/doc/but_01.png b/programs/other/cnc_editor/doc/but_01.png new file mode 100644 index 0000000000000000000000000000000000000000..5ca1e2d26106b0612b2af05f66c3b50df85b8520 GIT binary patch literal 360 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*BF(Nj+s z#}Etu-bpvPngT>zfB*0Q+I|bJp$2n{+w@o*F<}%H5Y8S)=G(tnCs&MXXy4Ag)>;ZH5^zNmZr{*YdoVed= zdn%FdbV{UKg<6Bfo!;6D9(5cBeahMo8T$9Lww*YCKtqn7wTel&;ahyu7SSi|OdXrs zKluDOr4}*mXj*m+1M9!Vs~=R#@v+Zwm_6&+8GcjigH0=E-Z2Dvn8DN4&t;ucLK6Vy Cj*H;{ literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_02.png b/programs/other/cnc_editor/doc/but_02.png new file mode 100644 index 0000000000000000000000000000000000000000..94187ab83a523364b55424646030f39c1e43caee GIT binary patch literal 645 zcmV;00($+4P)N2bZe?^J zG%heMGBNQWX_Wu~0s=`yK~y+TW7v1=KS_vyhQ^7@DmoXoPhABU!KWdiWGbB9G;tY_ zj4zo2(y(SpKQh|3vIDLT8HHr``e#mH0IIlkX~FjotAXg}yJf#$&tJ8$7fmS;1!wj7 zXH4`-pUkj&QQxL+Z%R1ICZd*0KdD*PSg;VS2POO>P zS2eY}5~!15@vOE_4<`X#a_>mPhUI;K?=}8^(1Jks8~@*}{(qz7|F!IkE5q`W{21m> zZT@(t^Z%osjVpSO@9F``!5woU{{PvKKS#a4?{>VsNG~VO9pt1r6C2)NZ+vjHcEhrs ze|H=HU(Nt2y_od>Y{Z}Ae&6@GecERIW{qKErfQ^%2uQ<>zS=jJD%URQK6j|||Bb@` zms9_ri}`ml@Yg}luRHDEZ7_McLi22^K(x0K)YDVDsxI%VTeqa^|DC%3=i~pM4*hk+ z=j$HF51Y+juhM(EK;=r0a6`JXftEB>!=(1|)eAeXY|1*@&j3Nkdsy~$aBOMfUs)qM zzg&7+k$kk5B1APvLw`$Ye?wY(WkPjcI4}?r!(4(qES;_NO!ZVXm89h)MZ|>oB!u}8 f8sIFV(5?Rf69^b93&47200000NkvXXu0mjffJirm literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_03.png b/programs/other/cnc_editor/doc/but_03.png new file mode 100644 index 0000000000000000000000000000000000000000..07ec7a2a9d6394c2b1f4bac50e73efe36948be67 GIT binary patch literal 491 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*AN17n7# zi(`m||J3eiZ>B&Ix8Ko!8yBQ&a`8;k6HsySu)E@|Z`n4pby@6&EtdkjrJRG7AB$el zV!K3C^JeQJjTVy}0k*VXNqlUkp0Z->-|l5^EpUAqU&ChTe$ISa%I2GD4h?QhQPVXl z?x}bR)id%lnFv+5CI8&INujIMF@Qy#a^L3i+(Wr8av1duHkD>Ugn*l za-!(xM>FZAMXXGM#~GOS+!L7K&Jq{&0zSU+m?k@v50lTmN9a$Wngx WSa-GmdRIY_$l&Sf=d#Wzp$Py|R=LUm literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_04.png b/programs/other/cnc_editor/doc/but_04.png new file mode 100644 index 0000000000000000000000000000000000000000..2edb10bc53964f03df6f4cfb225a451a4586c5d5 GIT binary patch literal 439 zcmV;o0Z9IdP)N2bZe?^J zG%heMGBNQWX_Wu~0W?WOK~y+TWBC970#>wS$>t+R_Wt{aE{v69F9;lbat-ZxN-ZhUpQ3*5mW=v$Te%W ztzEkfmrLLXs$u!^Evr^-{qf@*TmlyYX#l!==FIg!e-c&=L=2ZM9ZE`?w{6?bojZ3C zgBV`FKDB-OPT~>N5C8t1|MKOyv9Z?6m-~QhWCRpN2bZe?^J zG%heMGBNQWX_Wu~0c}Y{K~y+TW4KEqz^)-Q^c@gEIj8`O2B1L7egobqS7N4%L3`es4N)02B{UB7-EssaoU8jfsyw5Ijh z)VP<^!`@C0ec$E%uHNTGNAA5<3$9+gcoC`yS;N+;Pi7~-o)+?MM(~G8{vR8i-lrSB ziZ*@FR(j#k!9!3*$Qm|Jc{)4k&HSj3lLJ0Bxx6p6dY7X0HbCuRY5eikt5!o5A!}IO z{j4qEZJopWYTNfE=I_$AUx&!N@>9aC;mG#e%exC&Y`yRXiuxmyu&Bggl0PQb;coZ|~-Z`rhQ(~ccGpo)++T!4Z7`}c2HzX50} m5UpFc?!bWqP!&LM_bvbhwMPRAX529V0000N2bZe?^J zG%heMGBNQWX_Wu~0dGk}K~y+TW4H?g_wL<0d+@>1iWk%3UQdpAGa>ZNf|92v_uRUE z{W??y7$7tp+4yL6%d@F*FQUr?YEb9JuG*55vTS# zME-S`lI&{QB=w{G2m0|%fgzyP6vNPwcj<^O*mf^xtBQv^i=1H*qoBo#mg zkP8%qa3KIiLulwbh@Q}Q?|=x%5ET6H;(}WP5CHW66)^w}2CD{gp%O5F#nTWySXBc7 o77aiEREkwK5MbAU6WqNE03$m`0Vry&Q~&?~07*qoM6N<$f@m7j6aWAK literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_07.png b/programs/other/cnc_editor/doc/but_07.png new file mode 100644 index 0000000000000000000000000000000000000000..d1b7ba2de83e5030bb5bf18d8d3a59a3ba216d55 GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+L6~vJ#O${~L9r6oh?3y^w370~qEv>0#LT=By}Z;C1rt3(pZ7=q16ADeba4!^ z@Si$iBkv&t5f@`;wgt;hFez|VNl7TH3L7wZ2TV@A6XC_^d_hqqWnL{Gr<&TM6wPn{ zzyGt;TUVdOw4-FxwN;5#YP-In6g(&%$Nh6c6=dIaPyvsQes zV|?(;_41rVr3K#%=6Y?pcC|Qo*#U#OX1pw#tD~pxs8*P+cXE~2A9e=&e{!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*BFQH!UG zV~BTrr-kA4YXUM4o}8(=YuL2KIGdThC*qWb1Y_?-v3=6dFB|q3 z!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*BFQJbfW zV~B_F~)jR3QXX6j~+X$=GzvVgf` literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_10.png b/programs/other/cnc_editor/doc/but_10.png new file mode 100644 index 0000000000000000000000000000000000000000..adee03e9463fcd08b1fc2ac466c370b34ffc74f6 GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dj`K$uZp87V7l*mo|NhfXA-S?Tx(o4R_uhEB`Dj z()=^v*rgL11%|&hlmE1|s6O+*ZqBvAnaR16_Z3r1(uJ34>>H}POJ-HwP+7)0Q6y)5 zReR6UKs&LXgxxzx15`H#xaBM&4P zEqt3S`2rQ{x36P6q4>Wk!uBsyNj68DVI3p)?K}^Mjo-Hd-Ou3Z>gTe~DWM4fn(T6p literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_11.png b/programs/other/cnc_editor/doc/but_11.png new file mode 100644 index 0000000000000000000000000000000000000000..6cda650facac1f4ad4ef5976d55cdf4807d2abe6 GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dj`L74IQk1HTWk|nMYCBgY=CFO}lsSE{)nRz98d8s7|CVB>XMus01GN%F+eera0 z46*P}-r=ppkh!CgC2VcfQwHYC%Y2)=lo%(p$qL5?*QzRLoC@B#Z{5GUugfnl_v0_T z-qOAP<%a!LA5}t}(FK2Ij@#f;uqpn9^Ut7a0#ee0(-K%?3@477b(e2C{TIiMT zC+C>)<6qYCUf)8=my!;fCkkHJ_V=@L{F|O*>lh!Em^1_*{(jlgKHu+{%l-3W4=)rL ziSm98XLrbTWMVPNxxeqPzEDANvGSV4XJ2MkT2?xI`Ebv9kx9+351eutPi{>RRQQ^b z&7zj2|LIU3bI~OSH^y~UH*ycK9QeT2bnKYh8#9Kd3a>6O1TdR?czEC-Bg6NS51q{C SHfsR=&*16m=d#Wzp$Py|S((BB literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_12.png b/programs/other/cnc_editor/doc/but_12.png new file mode 100644 index 0000000000000000000000000000000000000000..855ffccfe6d5424407d2988e4e830354cbe3280c GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*BFQIe;N zV~B-+@(yn$i7Qh7)?0Hr2G~g?a4pKH&|b{sQjqB*sBmBr<07VB?$DNJ>?y7VEo-DW zF4*=iWA`-`2w2AGYs#|l<-!A(3q-+c9WF9J4XB=_pb&WY?rw$|{E@HA3+^lh+Q#7N L>gTe~DWM4f!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*BF(Opj$ z#}EtusS~2Pnj9orqrG#Ne!J)v73dhvQFUH#nNsK7V{Z<{A9gWaqW4SRHB7Zy|c0B41MK!dn=>7Qu4o4HKwOZh-x+SmP$vk229rw1Tvn?getW(bl9qtdgFuB2_Nw}j`e&vGe+?Q`&O*~}hy})t3 tc%AcRw;x>l*4Is5EdGK&OXmD<27{H!capAKbO1fd;OXk;vd$@?2>?jDhLQjP literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_14.png b/programs/other/cnc_editor/doc/but_14.png new file mode 100644 index 0000000000000000000000000000000000000000..a38ac674320f2f84ea5d3ee8188f6e55030d9e31 GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*BF(H&10 z#}Etu9ZJ$0BEs*=e ru!3!c(5glihF(66et{i@kJ%WqUT!MAC41^P(4P#Ru6{1-oD!M<+sAi0 literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/but_15.png b/programs/other/cnc_editor/doc/but_15.png new file mode 100644 index 0000000000000000000000000000000000000000..b5154cbd9f091d4bfe2295f05e11f96274d038bc GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXJq(MA#*BFQI4mJ zV~B=G@aIKI!BRscD|OUA|0;b$IeI>3$^JgTi*Ngw*C( zg`!JgTe~DWM4fnLtt< literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/cnc_01.png b/programs/other/cnc_editor/doc/cnc_01.png new file mode 100644 index 0000000000000000000000000000000000000000..efc88ee88471a5b98d785ed27064bc2567ea6922 GIT binary patch literal 24075 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 z {I+9Gnz-qrNc23A3@g5>ooMMXslC7bZ#QGnvu{8(Gm#-O{eJdTQk)b!cYs1Vt z@1=-ka;;W&jzRc{b}Rb78z#n;)L z{|aG38r@WPz{l8_jH2fv4mf8~KjV#*VX}F(=IdJN>MK|NcU+0zK=*KFikqA?bs))A z%Je{sA{O6LL8#neFyxiPVAvN7HOrTznJ9|yVs?d8ccjDp1u{Rw*ENM+rsxX2NP?($ zO~*C$e_5Oxv{)^SGEpnkChM=rCNgFOkgStPtKVT3ch(^T54$MW!E8-GU&rHtv!7iZ zXZ?J6j~^13vFiy6ZFHz7K7^8?H-Dt?`eSiNb7einTNiF6+H7rZ9w(=CwSYLc%-7nH zWHFIo+IZx$l71!za$Yosv~Quo-xPAwY#Z~lVy}jUCwwTK+ovU$!LxhJ`^}*>xGRv! zWOxDhX{(i50zhADC!deCe;_d&oGXi_V@rz$5=XEv`Z5otS_M{6vc$nw& z3>{FpfwkwxTsM#Q)hu%bECDdas7-LIJ#K%<3{jgSfwef(UXSl%hmo0ZF52vc+}RLO zAyWV=I1Eixh1ZB#u4pR!hfl#Si|BJI843upHiU^7wWxDS&X0P8ma+F&B5JFwq+pDx zN8E)}ApYk7*$A(mQ{i$Vj_?>3!#y_y-pKhFiMt$yFroYpA~CMn{AsE8ERSowFd9_$ z7PIAB~Rd+4BpKeNBMT@AcX z*TOss2DAAcR9-2ZN(>^XCb%8EHnIj;9r?0JQJADr z260(8JMMn<3gBO+6a^M#k2KK@KORsO(t%F`aUZNOCh=;f7po5}K_Wc=Y zDgoQQc?nj`&ag06{`0~?Y?)Q%U{OWDG++%2{7?1LG`8*Vk>jHKENd-AHIWf(4Z@w` z12mRZfsw!K4{j(XMDIgQ4)sjs z%yCD8@Y5giz3XrHb;?pkv|W;*@uZmr*u$vVmsK`ziYgm4*lT;Jqo2be9(j4;cE z#+iRT%7P8Vn-#qLL{J-SoRJymS4~rB0)5^M8tVM-&D^zTJcY2P4g|CQM@A)j{v-Yh zq0Kz!+~@wd_wP>j z+G~C5TVH+ORcJk_`9;J=f< zDP{-Qx+*fq!Jq)Y2yn;_=Be&GsOs3%J-Uxva5}%4*U+4vwVK=AO{iK`*Q~)io`bbr ztu?8mT9ZTT79`el{1Uk(OSjs^?9RD2G8a#&-buGEyYwa2TG!xbKk7Y_^i1yiA`)9l z&)Rj`=kY?1oE_V)Y0pu>3T3|6U$y|zGTsS7M>Ue05*=MH^&Nz4Q6E+0 zWOEs)2Z$CTl0E5^5}wN8Dmq4sr!_q2L5ppDCMToiC|8ymBKJK!!}VCe@{_hK?_%+> zLO!-H?d+qbX}?-ui#-XvQ185>$1ZES?&deo5VmD@rg;0NLgLEXdognyRRlMnI^znM z+NC=8Km4T9xWrzs)?1$@cDMwyJo)@{EZM%~M{|~{b0zw> z`K$=}RzJqV(6P$F!IJ0B|Drkqd)Txh3rh;%IUCK99DU8DqXGYyT41#C<;>nibr~-Q zYPR(tCi(qKYvzdkAz#q*n%SAnF}u3P{sbBKSN#l&exu0i=`q`|uen%iyWVhTavWvs zAnuwQyMlYrTPkZe?}_jK!!S(Hq#2HNYEHYkSD{o3!43al+7w50twGW9ZM!$oA5CO~g`czOMdSPFELd7o9o&8RRnL!9ynKee(rU1B z{AR?41L5Hzwh54}-c{kr1&KP2jla^DcRy##Bqz)}LGRk|W#x9S>t>4_r3>mjBW^kX zn-5@XTRQ3>cx+KSlZKy)>K|j2!Gvqd10v=*e;4H$YZ!HQVjXY%~ z9z=Kgx%-qmHr2`C)5u8rpxf8^=0q+~4@8o&+!tuNsa2G}ZhN0~261stZ$<2eBN8ud z$+^snv8ZcJbKXW4PD78hY!VX?g!

FlK#Nm;RKtCC<=euPzoD{ zuxFR7_Fhc*r_y|8z!C`qE@ZRlLB)2QSm-SrQ+md&UibZg(bQFA_81N?S6gOK@{lUTH%AIO`CYrYKaT(no&|H-&EJA?B1Pa`szDnx^ ztK>|5%&k`qe>xE-TH%3LciA~+e4e14voOcsFxB3aZGxX+gm&y>)d#QuWG$mdAaq;3 zLc(!-&rWD}1~Jh1gTwT2yweR$hY&);1y`Yp_=05b-XTzt$kl-|5AV751_bnjBD-9< zX?i#8m(m+vkdY{U^_R}ULC{Zl7W}pA7Z)ERXvpWNa#{WQJ?MPdlTrg25_41r?=$w& z66`MEIa-dOf8#$b75r3{J3)2Ogli-HR}-xHf3`zx~s z$gJdjMLV9~FSO|+ax=Zz)VwIP{5D-POU+B#4|>YU@DS3MTt`CiT%Dl!)Wkgf;IX?H zEw)IrLw|!l{5_GbOJLU|MBNL!?Y+9({Dd|bUXY5#+j}SAJfXraDAPT5(#D5yp|phY z2oB;o=jBzfBoiAhlJCm@+%ZZxFdD23L7pGR{!ajg3%ljd%FlmUFgbx~Ql2+~bF9JP zqlR(-v-emf`-4Z$qbJN+GscHj)l_>TNF(;)bl`L4@rR;kst7{@O6)HNjLCpX&=QX} zc-Z6du-s03TlIZkIS+Ye^m>}ReY8#poD3G4x(N-YU+QpIKYpSZs3m)6m=m>t z01@Cl=Wyf>VgzXx1iiNYm^om10r2iT{rSex^3#6l@xx4+Mdnq2! zvjolSf5doE3%Ar)HsL(o{`vY^3&dAawph#^Bq26|4v4{M7C0n8EM22H=Ee@N6*Ty1 zcuVsHM$0XoR}wi?`PC?Py9=-Uq_~K9t}bG*B>C0wWee&O0%K-pkH@B-Q{_3;T?rbj z6koxZ{TJlZIyEi?JWMK3;Ub2SI_-Q?{YnNewt07J?Wf8I#98TkS`GKWIc{~|4vp(FrMj{O9sJL223>kwP& z2-b)QHj%?>sv-K9Q1f{Q&PLj}S z3NI4SMQU6`1>7lt`aJ!cj(e~qr;N#>ofayMwoM8JIKkHa{aLRjbhkZ65Ujh zj;2SS@BYI0qjhEvs_&zOW6(v19zbs8k10y?eR^$DwDS0BAgtJ%#hk?+W3HX0H0>Mf zIRkpG+93vhxqdxRYe6fvslejBkWFi^u?0}}aaDI*}gW_wA7cr4Vl2X`-S z1Uu4r;tV&FD--n$@~I!#`KnJvd8zCjR@xv2131GqO5)(AVp=_Q<)iBIr7@ax5Hu( zr-S!|&|UjIcIGN)qTFHuH+D4hDX8R-_rpq>gz+ymwtl+Sd^ z1KednyQmKX+3=Igx;ji?Dx8?J4FPFu%TUZtoKDhdODT}yA{G}=-?T=2;~Mh?3~4D2 zH6?o&TTA4aZJf$^Y<}X3DL0sunSudHe8|XxK)tnFzGj~Lta z_ZiYjNJatN0KkeSyli?TpYLRT>$~%8?_SE%T=Y>>R!dkzHl0h-8c4R~G#YOH8jS~0 zN483P1AwT3u?~T;B2Gb{^Dhy8vqG9@BGD~`jFPYpRT0oJ&i^sl$zIc*hng@6L)T(B zqH0ZMZm=OLvDta(f~6?lgC!i0oj>M2qJFo~XD}$Nt=o>1P(5hv8c74Qx~2|h$ukg} zh)(1_i9NJ`ZlM=Y>~`m(Cj9%Z5KetEP`khk8FJzdZ=Q|2mzOa5S6{R>}?&YrtZk9 zG~f>89Jj}$xXWgG{CSI?avIBr)PY1Gb_gl>@zG$Io=TZt46YXN2JH8cn<&ef2n*{xUBcP zW4yJ){@vBLtz=n+LAz)FcCuIfbvF>9a08DHxN*OSj2?4d={wXg6DWxpc&`8PLlVG3 z_Ek5=yB&C%x@ueZ{RU2?`dDWTfW4|>LtaS=L7#C5Y7J<+CZg?}na*pCxW1h4Dx^z< z>_#}ly>Bb>AME*(wz3eC8G}PS4y3Ub&~jLh7Hdx1OJ)5&)KsFB>g5J5?98_`{A%-i zwLJ6qkPz`_&1;~giI&-7l?iY4+Af0+E}6h(k(GL1MY∾LHhysk7g{{L2LN5hu?s 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 Pe-!0Z@4S*R3H-kROZjqj literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/cnc_03.png b/programs/other/cnc_editor/doc/cnc_03.png new file mode 100644 index 0000000000000000000000000000000000000000..29aac13df261c33224bcadd5b070b67699d64723 GIT binary patch literal 3523 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 LE8}uQ*T{bYdUIi^ literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/cnc_04.png b/programs/other/cnc_editor/doc/cnc_04.png new file mode 100644 index 0000000000000000000000000000000000000000..c081ce6954fe27d529efaa22381fb50644421aae GIT binary patch literal 2905 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 a$1FEc;LSSRd>-?k0WvW%H7qf(fBX;KLoPG` literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/cnc_06.png b/programs/other/cnc_editor/doc/cnc_06.png new file mode 100644 index 0000000000000000000000000000000000000000..abd3cd51f0bd377b33ffc06c60c049705c32f717 GIT binary patch literal 2439 zcmeH|Yg7_w8pmmknsl1nMl;Hq-Xp!21R?f}3Z2i3jsD>W6n-|A+l(%w*q%PO%sN8@ua5CBjExIsLfRJx_5 zrM1`7`lj|dBkjEqDe5J)7_DgX7&vQAieH}W9?hU zkX#$tA^6^qYRYVMJOhVYXXmd38t%RABef+7Y6`*)BEM@(FXmRsuFb(PQD0_=nzCga4Z}U6MQ=g zVIBoX7+RU1Hb3(>nc?lH003~q`J#g-61p-aLVfF{H6Y8Xgz7U3KU9LcG%#9ejsdsB zF)lF`U%jI0m1t#J?aOlqnbNS54ngUANCC$=ZmU-}1#7iVXF4zbV{s4yb&I*~5tGA_ zEw~AwyY0u_H{(5H^e2yJ+>0hW?;2#+v@aVpG&CC768%Ef*nN;rYzeAdRV`*Ve)y-RRcDC7i!E%ce`uV0khQJb& zD_0~PV_~dm%b)#9LyQ@|Py!l$By`7Mfl5yk7Fj` z;G@!{(@2j3qclJGx~Sv%{>9m)EluHmEJ)lP4o1PoAv1ihCLUF=;@X zz0tzubteP}DkuWKmp|Ono*p6ua6U#uT8){AYqy)m@OXSEeOOZ`(BBt_mYWS5AtROP z=R;;L9pkFWI@yAu?I2R^_O$0goliQ=1L(i(o}sqCpbvSF!_9^{0K0;bW8KBJ-*1oD z9LImBoZn+FPWj2JPn>AIwm}Wr_$w9YLyXT>hw5L##eu!z?`>`7>?Cv72*`w07loJU zS?k>Mf}~Dx+c^k+SDQ7EdHh;g2_EgU@364cbvy1SMELHDTO!T z(AIDN1Z;2{R{sz9;3>tI5d<`?0P-Z=(cwi+%RC27Lg-F&94n;W1D*9%+0I24zDRz5 z1v;wc=Zl36C4o(Et6{KG!p$J>(f+Ds9kUJ6N&E*}nc%aB*+K5%tA$A7d5!Lq#H4ff zsE$+bEb98K@uX=5byjBM1hF`3S0d}Q=+}mq{W8NF-b7(GorHb`s2}_}6SwSAM)!B` zPqrkP^9&R>L&16JXr(?Yx#h4<7K49OWcqAl!sX>4Mlu+G!`S2`aMNfd?$8^?j@{I{ z$s(HQ+FZY(9BC~Lbp9}5_dMZPPVD#4)eU{7s{i&#(4{~8M*tIw%dI^iz%(3ATiw6n ze*t&3m_J(C?HQ{!5*}zV_KRVJUT_KgOfNM)XQR;ruF|nlU*f(o9?H`P-O50FgKkX( zNhzx3=uE66-_@zgkBAgCllgc<{<+|;c(6u;-D{xe*Eb4-yy94&uy5xi6C|AdfqVJ% zQIvVmI!~j+^m+8Xw8WK>Vz%U|yPMu-R5IOIoak*3>+1$hDtsqgHR_o%uLbhImSvI} zza#NlQ$#SR`qJuk?$T!SMDonyDal6)Dz}FskTvo;kU>L&-8-@FZYi~uFMe~8w*__6 ze3-`7hS)(YosrqY2G{NCDa&e5F=tsoVB7RQEiKU5EG4i_0|-?AM(qpm_<4EX66ksO zY~c>tx?I1wJXJKRsn|O`dR6m5>KDg<*#0+oYMPa9A94^SMAbYV>;JO3oSm**eCc={ F{V&mmI1T^+ literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/doc/readme_ru.htm b/programs/other/cnc_editor/doc/readme_ru.htm new file mode 100644 index 0000000000..add0d6181e --- /dev/null +++ b/programs/other/cnc_editor/doc/readme_ru.htm @@ -0,0 +1,114 @@ + + +CNC_editor + + + + +

CNC_editor тхЁёш  14.09.18

+ +

╬уыртыхэшх

+
    +
  • ╬ яЁюуЁрььх
  • +
  • ╧рэхы№ шэёЄЁєьхэЄют
  • +
  • ╩ыртшрЄєЁр
  • +
  • └тЄюЁ
  • +
+ +

╬ яЁюуЁрььх

+

CNC_editor - яЁюуЁрььр яЁюёьюЄЁр ш ЁхфръЄшЁютрэш  Їрщыют ЇюЁьрЄр *.nc. ╘рщы√ *.nc ёюфхЁцрЄ т ёхсх ъюф (gcode) фы  ёЄрэъют ё ╫╧╙ (ўшёыютюх яЁюуЁрььэюх єяЁртыхэшх шыш эр рэуышщёъюь CNC). ╩ Єръшь ёЄрэърь юЄэюё Єё : ырчхЁэ√х уЁртхЁ√, ЇЁхчхЁютры№э√х ёЄрэъш, ётхЁышы№э√х ёЄрэъш, яыюЄЄхЁ√. ═р яюїюцхь яЁшэЎшях ЁрсюЄр■Є 3D яЁшэЄхЁ√ Єюы№ъю шёяюы№чє■Є фЁєующ ЇюЁьрЄ фрээ√ї *.stl.

+ +

+

╨шё. 1. ┬эх°эшщ тшф яЁюуЁрьь√ ё юЄъЁ√Є√ь Їрщыюь *.nc

+ +

┬ючьюцэюёЄш яЁюуЁрьь√:

+

╬ЄъЁ√Єшх Їрщыют ш яЁюёьюЄЁ ЄЁрхъЄюЁшш фтшцхэш  ёЄрэър. ╠юцэю шчьхэ Є№ ъююЁфшэрЄ√, фюсрты Є№ Єюўъш т ЄЁрхъЄюЁш■, єфры Є№ Єюўъш, ьхэ Є№ яюЁ фюъ Єюўхъ фтшцхэш . ═х тёх фрээ√х ЁхфръЄшЁє■Єё  яЁюуЁрььющ, эряЁшьхЁ: єёЄрэютър ёъюЁюёЄш фтшцхэш , яюфэ Єшх/юяєёърэшх °яшэфхы  т яЁюуЁрььх шчьхэшЄ№ эхы№ч . ╤юїЁрэхэшх ЄЁрхъЄюЁшш фтшцхэш  т Їрщы *.png. ╩юф gcode шьххЄ ЁрчэютшфэюёЄш т чртшёшьюёЄш юЄ ёяхЎшЇшъш ёЄрэър, яюЄюьє эх тёх Їрщы√ *.nc ьюуєЄ ъюЁЁхъЄэю юЄюсЁрцрЄ№ё  фрээющ яЁюуЁрььющ.

+ +

+

╨шё. 2. ╧ЁюёьюЄЁ Єюўхъ фтшцхэш  ёЄрэър

+ +

╧рэхы№ шэёЄЁєьхэЄют

+

эют√щ Їрщы. ╧Ёш ёючфрэшш эютюую Їрщыр ьюцэю т√сЁрЄ№ ЇшуєЁє юъЁєцэюёЄ№ шыш яЁ ьюєуюы№эшъ. ╩юЄюЁ√х яюЄюь ьюцэю ЁхфръЄшЁютрЄ№.

+

+

╨шё. 3. ╬ъэю ёючфрэш  эютюую Їрщыр

+ +

╧рЁрьхЄЁ√ фы  ёючфрэш  юъЁєцэюёЄш:

+
    +
  • X0, Y0 - ъююЁфшэрЄ√ ЎхэЄЁр
  • +
  • R - Ёрфшєё юъЁєцэюёЄш
  • +
  • S - ъюыышўхёЄтю уЁрэхщ
  • +
  • Z0 - ьшэшьры№эр  (Ёрсюўр ) т√ёюЄр шэёЄЁєьхэЄр
  • +
  • Z1 - ьръёшьры№эр  (схчюярёэр ) т√ёюЄр шэёЄЁєьхэЄр
  • +
+

╧рЁрьхЄЁ√ фы  ёючфрэш  яЁ ьюєуюы№эшър:

+
    +
  • X0, Y0, X1, Y1 - ъююЁфшэрЄ√ єуыют яЁ ьюєуюы№эшър
  • +
  • Z0 - ьшэшьры№эр  (Ёрсюўр ) т√ёюЄр шэёЄЁєьхэЄр
  • +
  • Z1 - ьръёшьры№эр  (схчюярёэр ) т√ёюЄр шэёЄЁєьхэЄр
  • +
+

юЄъЁ√Є№ Їрщы

+

ёюїЁрэшЄ№ Їрщы

+

ёяЁ ЄрЄ№/яюърчрЄ№ эюьхЁрЎш■ Єюўхъ

+

, яхЁхьх∙хэшх т√сЁрэющ ъюьрэф√ т ёяшёъх

+

т√чтрЄ№ фшрыюу ёючфрэш /ЁхфръЄшЁютрэш  Єюўъш. ┼ёыш эш юфэр Єюўър эх т√сЁрэр, Єю т√ч√трхЄё  фшрыюу ёючфрэш  Єюўъш. ┼ёыш т√фхыхэр юфэр Єюўър Єю т√ч√трхЄё  фшрыюу ЁхфръЄшЁютрэш  ъююЁфшэрЄ Єюўъш.

+

+

╨шё. 4. ╬ъэю ёючфрэш  Єюўъш

+

+

╨шё. 5. ╬ъэю ЁхфръЄшЁютрэш  Єюўъш

+ +

, яхЁхьх∙хэшх т√фхыхээ√ї Єюўхъ ттхЁї шыш тэшч т яЁхфхырї т√сЁрээющ ЄЁр¤ъЄюЁшш

+

ъюяшЁютрэшх ъююЁфшэрЄ т√фхыхээ√ї Єюўхъ т сєЇхЁр юсьхэр

+

тёЄртър Єюўхъ шч сєЇхЁр юсьхэр. ╘юЁьрЄ ЄхъёЄр фы  тёЄртъш т сєЇхЁх юсьхэр: 'X_ Y_\n...\0'.

+

єфрыхэшх т√фхыхээ√ї Єюўхъ

+

ёсЁюё ьрё°Єрср ш ЎхэЄЁютър Єхъє∙хщ ЇшуєЁ√ яю ЎхэЄЁє юъэр яЁюёьюЄЁр

+

ёюїЁрэхэшх ЄЁрхъЄюЁшш т Їрщы *.png

+

эрёЄЁющъш ЁрчЁх°хэш  фы  ёюїЁрэхэш  Їрщыр *.png, єърч√трхЄё  ўшёыю яшъёхыхщ эр 1 ьь. ╧ю єьюыўрэш■ єърчрэю ўшёыю 11.81102362204724 (фы  яхЁхтюфр т dpi: 11.81102362204724 * 25.4 = 300).

+

+

╨шё. 6. ╬ъэю эрёЄЁюхъ ЁрчЁх°хэш 

+ +

╩ыртшрЄєЁр

+

Delete - єфры хЄ т√фхыхээ√х Єюўъш.

+

┼ёыш эх єфрхЄё  ь√°хщ т√фхышЄ№ юфэє ъръє■-ышсю Єюўъє (эряЁшьхЁ ъюуфр хх ъююЁфшэрЄ√ ёютярфр■Є ё фЁєушьш Єюўърьш, Єюуфр т√фхы ■Єё  ёЁрчє тёх ёютярфр■∙шх Єюўъш р эхюсїюфшью тч Є№ Єюы№ъю юфэє), ьюцэю тюёяюы№чютрЄ№ё  ъєЁёюЁрьш:

+

, - яхЁьх∙рхЄ т√фхыхэшх Єюўъш ттхЁї, т√фхы хЄё  яЁхф√фє∙р  Єюўър.

+

, - яхЁьх∙рхЄ т√фхыхэшх Єюўъш тэшч, т√фхы хЄё  ёыхфє∙р  Єюўър.

+

Ctrl+N - ёючфрэшх эютюую Їрщыр.

+

Ctrl+O - юЄъЁ√Єшх Їрщыр.

+

Ctrl+S - ёюїЁрэхэшх Їрщыр.

+

Ctrl+A - т√фхыхэшх тёхї Єюўхъ Єхъє∙хщ ЇшуєЁ√.

+ +

└тЄюЁ

+

IgorA

+ + + \ No newline at end of file diff --git a/programs/other/cnc_editor/kolibri.NC b/programs/other/cnc_editor/kolibri.NC new file mode 100644 index 0000000000..0404a40ab2 --- /dev/null +++ b/programs/other/cnc_editor/kolibri.NC @@ -0,0 +1,789 @@ +;PCB graving +G0 M3 X0 Y0 Z5 + +G0 X40.28 Y38.95 Z5 +G1 F100 Z0 +X40.28 Y38.95 +X39.46 Y38.44 +X37.03 Y36.89 +X35.56 Y35.99 +X34.9 Y35.63 +X34.41 Y35.35 +X33.74 Y34.97 +X32.97 Y34.52 +X32.69 Y34.35 +X32.38 Y34.35 +X32.1 Y34.43 +X31.82 Y34.51 +X31.18 Y34.6 +X30.54 Y34.7 +X30.03 Y34.78 +X29.52 Y34.85 +X29.1 Y34.88 +X28.68 Y34.9 +X28.6 Y34.96 +X28.37 Y34.96 +X28.22 Y34.9 +X28.27 Y34.81 +X28.62 Y34.65 +X28.96 Y34.49 +X29.16 Y34.42 +X29.72 Y34.17 +X30.08 Y34.01 +X30.7 Y33.81 +X31.32 Y33.61 +X30.98 Y33.43 +X30.34 Y33.21 +X30 Y33.08 +X29.78 Y33.04 +X29.77 Y32.87 +X29.76 Y32.7 +X29.89 Y32.58 +X30.02 Y32.46 +X30.12 Y32.46 +X30.67 Y32.3 +X30.03 Y31.51 +X29.8 Y31.16 +X29.41 Y30.53 +X29.19 Y30.13 +X29.19 Y30.08 +X29.22 Y30.06 +X29.24 Y30.06 +X29.69 Y30.24 +X29.36 Y29.88 +X29.03 Y29.52 +X28.49 Y28.91 +X27.95 Y28.29 +X27.54 Y27.8 +X27.46 Y27.71 +X27.08 Y27.34 +X26.7 Y26.96 +X26.61 Y26.89 +X26.04 Y26.5 +X25.56 Y26.31 +X25.07 Y26.13 +X24.8 Y26.06 +X24.54 Y25.76 +X24.43 Y25.76 +X24.32 Y25.76 +X24.06 Y25.63 +X23.8 Y25.5 +X23.69 Y25.42 +X23.59 Y25.33 +X23.43 Y25.1 +X23.27 Y24.87 +X23.08 Y24.69 +X22.89 Y24.51 +X22.74 Y24.21 +X22.58 Y23.9 +X22.51 Y23.7 +X22.43 Y23.49 +X22.37 Y23.23 +X22.31 Y22.98 +X22.22 Y22.96 +X22.13 Y23.01 +X21.93 Y23.2 +X21.72 Y23.37 +X21.28 Y23.85 +X20.83 Y24.29 +X20.45 Y24.58 +X20.13 Y24.78 +X19.81 Y24.93 +X19.65 Y24.97 +X19.49 Y25 +X19.36 Y24.95 +X19.24 Y24.9 +X19.15 Y24.82 +X19.07 Y24.73 +X19.07 Y24.55 +X19.07 Y24.36 +X19.32 Y23.59 +X19.43 Y23.26 +X19.53 Y22.93 +X19.59 Y22.64 +X19.83 Y22.38 +X19.99 Y21.8 +X20.12 Y21.45 +X20.24 Y21.18 +X20.24 Y21.09 +X20.6 Y20.69 +X21.04 Y19.79 +X21.19 Y19.54 +X21.33 Y19.49 +X21.47 Y19.36 +X21.8 Y18.84 +X21.89 Y18.74 +X21.98 Y18.56 +X22.3 Y18.17 +X22.34 Y18.07 +X22.38 Y17.97 +X22.28 Y17.79 +X22.05 Y17.71 +X21.85 Y17.73 +X21.26 Y18.02 +X20.68 Y18.31 +X20.45 Y18.4 +X20.22 Y18.5 +X19.4 Y18.9 +X18.91 Y19.07 +X18.43 Y19.24 +X18.29 Y19.33 +X18.16 Y19.42 +X18.13 Y19.42 +X18.1 Y19.42 +X17.85 Y19.57 +X17.61 Y19.72 +X16.99 Y19.92 +X16.38 Y20.13 +X16 Y20.19 +X15.62 Y20.25 +X15.26 Y20.33 +X14.9 Y20.41 +X14.57 Y20.45 +X14.24 Y20.48 +X13.83 Y20.6 +X13.42 Y20.71 +X12.65 Y20.91 +X11.88 Y21.12 +X11.63 Y21.16 +X11.37 Y21.21 +X11.04 Y21.28 +X10.71 Y21.36 +X10.3 Y21.44 +X9.89 Y21.52 +X9.1 Y21.65 +X8.3 Y21.77 +X7.79 Y21.83 +X7.28 Y21.88 +X6.43 Y21.88 +X5.57 Y21.88 +X4.68 Y21.77 +X3.86 Y21.58 +X2.94 Y21.25 +X2.71 Y21.1 +X2.48 Y20.94 +X2.41 Y20.87 +X2.34 Y20.8 +X2.36 Y20.69 +X2.38 Y20.58 +X2.58 Y20.44 +X2.79 Y20.3 +X3.09 Y20.22 +X3.4 Y20.14 +X3.68 Y20.14 +X3.96 Y20.14 +X4.2 Y19.89 +X4.44 Y19.65 +X4.77 Y19.44 +X5.11 Y19.23 +X5.12 Y19.29 +X5.14 Y19.34 +X5.36 Y19.05 +X5.57 Y18.77 +X5.76 Y18.62 +X5.96 Y18.48 +X5.98 Y18.45 +X6.01 Y18.43 +X6.11 Y18.36 +X6.21 Y18.3 +X6.39 Y18.22 +X6.57 Y18.14 +X6.64 Y18.08 +X6.71 Y18.02 +X6.84 Y18.01 +X6.98 Y18 +X7.07 Y18 +X7.16 Y17.99 +X7.35 Y17.79 +X7.54 Y17.58 +X7.6 Y17.58 +X7.66 Y17.58 +X7.68 Y17.51 +X7.71 Y17.44 +X7.86 Y17.36 +X8 Y17.29 +X8.25 Y17.15 +X8.51 Y17.02 +X8.57 Y17.04 +X8.63 Y17.07 +X8.66 Y16.99 +X8.69 Y16.92 +X8.8 Y16.93 +X8.92 Y16.95 +X8.92 Y16.82 +X8.92 Y16.7 +X9.15 Y16.53 +X9.38 Y16.36 +X9.58 Y16.25 +X9.79 Y16.14 +X9.89 Y16.05 +X9.99 Y15.96 +X10.24 Y15.9 +X10.49 Y15.83 +X10.64 Y15.84 +X10.79 Y15.84 +X10.84 Y15.74 +X10.89 Y15.64 +X10.95 Y15.64 +X11.02 Y15.64 +X11.4 Y15.39 +X11.77 Y15.13 +X12.04 Y15.05 +X12.31 Y14.97 +X12.5 Y15.01 +X12.68 Y15.04 +X12.67 Y15 +X12.67 Y14.95 +X12.67 Y14.9 +X12.68 Y14.84 +X13.21 Y14.57 +X13.74 Y14.3 +X14.02 Y14.29 +X14.3 Y14.28 +X14.37 Y14.23 +X14.44 Y14.17 +X14.59 Y14.1 +X14.75 Y14.02 +X15.07 Y13.91 +X15.4 Y13.79 +X15.68 Y13.79 +X15.95 Y13.8 +X15.98 Y13.73 +X16.01 Y13.65 +X16.29 Y13.55 +X16.57 Y13.44 +X16.66 Y13.44 +X16.74 Y13.44 +X16.8 Y13.29 +X16.86 Y13.14 +X17.02 Y13.1 +X17.18 Y13.07 +X17.18 Y13.03 +X17.18 Y12.99 +X17.4 Y12.93 +X17.63 Y12.87 +X17.72 Y12.77 +X17.8 Y12.68 +X17.86 Y12.68 +X17.92 Y12.68 +X18.07 Y12.52 +X18.22 Y12.37 +X18.43 Y12.27 +X18.64 Y12.17 +X18.97 Y12.17 +X19.25 Y12.36 +X19.32 Y12.46 +X19.43 Y12.55 +X19.54 Y12.65 +X19.62 Y12.8 +X19.7 Y12.96 +X19.7 Y12.86 +X19.54 Y12.36 +X19.37 Y11.86 +X19.3 Y11.44 +X19.23 Y11.02 +X19.25 Y9.53 +X19.27 Y8.05 +X19.33 Y7.69 +X19.38 Y7.34 +X19.48 Y6.93 +X19.57 Y6.52 +X19.63 Y6.21 +X19.68 Y5.9 +X19.74 Y5.7 +X19.79 Y5.5 +X19.84 Y5.11 +X19.89 Y4.73 +X19.97 Y4.5 +X20.04 Y4.27 +X20.09 Y2.58 +X20.13 Y0.88 +X20.21 Y0.74 +X20.28 Y0.59 +X20.39 Y0.49 +X20.5 Y0.39 +X20.5 Y0.5 +X20.5 Y0.6 +X20.69 Y0.64 +X20.88 Y0.67 +X20.97 Y0.76 +X21.07 Y0.84 +X21.27 Y0.83 +X21.47 Y0.82 +X21.8 Y0.94 +X22.12 Y1.06 +X22.31 Y1.21 +X22.49 Y1.35 +X22.49 Y1.4 +X22.49 Y1.44 +X22.59 Y1.58 +X22.69 Y1.71 +X22.75 Y1.94 +X22.81 Y2.17 +X22.81 Y2.29 +X22.8 Y2.41 +X22.78 Y2.54 +X23.56 Y3.07 +X23.67 Y3.27 +X23.77 Y3.82 +X23.87 Y4.37 +X23.91 Y5.38 +X23.94 Y6.39 +X24.07 Y6.99 +X24.27 Y7 +X24.4 Y6.85 +X24.47 Y6.85 +X24.75 Y6.98 +X25.02 Y7.03 +X25.04 Y7.05 +X25.26 Y7.35 +X25.71 Y8 +X26.06 Y8.49 +X26.04 Y8.87 +X25.87 Y9.12 +X25.87 Y9.28 +X26.14 Y9.69 +X26.41 Y10.1 +X26.81 Y10.71 +X27.1 Y11.22 +X27.75 Y12.55 +X28.17 Y13.72 +X28.21 Y14.08 +X28.33 Y15.16 +X28.3 Y16 +X28.25 Y16.92 +X28.16 Y17.66 +X28 Y18.5 +X27.85 Y19.35 +X27.99 Y20.78 +X27.98 Y21.52 +X27.97 Y22.26 +X27.86 Y23.13 +X27.76 Y24 +X27.71 Y24.61 +X27.63 Y25.73 +X27.62 Y26.44 +X27.91 Y27.07 +X28.33 Y27.68 +X29.15 Y28.78 +X29.44 Y29.15 +X30.03 Y29.78 +X30.59 Y30.35 +X31.15 Y30.92 +X31.27 Y30.83 +X31.84 Y30.76 +X32.21 Y31.09 +X32.58 Y31.41 +X32.7 Y31.51 +X32.81 Y31.59 +X32.89 Y31.41 +X32.9 Y30.9 +X32.9 Y30.39 +X32.95 Y29.52 +X33 Y28.65 +X33.04 Y28.59 +X33.08 Y28.52 +X33.15 Y28.6 +X33.23 Y28.67 +X33.23 Y28.88 +X33.23 Y29.09 +X33.3 Y29.46 +X33.38 Y29.83 +X33.43 Y30.26 +X33.48 Y30.69 +X33.48 Y30.83 +X33.66 Y30.73 +X34.1 Y30.65 +X34.53 Y30.58 +X34.86 Y30.52 +X35.19 Y30.47 +X35.76 Y30.41 +X36.32 Y30.35 +X36.36 Y30.31 +X36.4 Y30.28 +X36.05 Y29.96 +X35.71 Y29.64 +X35.48 Y29.55 +X35.37 Y29.31 +X35.26 Y29.07 +X35.4 Y28.95 +X35.53 Y28.83 +X35.67 Y28.82 +X35.81 Y28.82 +X36 Y28.84 +X35.93 Y28.62 +X35.64 Y28.19 +X35.41 Y27.68 +X35.19 Y27.09 +X34.98 Y26.5 +X34.94 Y26.42 +X34.9 Y26.33 +X35.04 Y26.35 +X35.18 Y26.36 +X35.23 Y26.45 +X35.28 Y26.53 +X35.59 Y26.74 +X35.91 Y26.96 +X36.63 Y27.59 +X36.85 Y27.8 +X37.07 Y28.02 +X37.21 Y28.17 +X37.26 Y27.99 +X37.47 Y27.58 +X37.75 Y27.42 +X37.88 Y27.42 +X38.01 Y27.43 +X38.13 Y27.5 +X38.24 Y27.85 +X38.35 Y28.19 +X38.53 Y28.6 +X38.6 Y28.89 +X39.1 Y27.86 +X38.99 Y27.65 +X38.87 Y27.44 +X38.53 Y26.79 +X38.19 Y26.15 +X37.65 Y25.05 +X37.11 Y23.95 +X36.84 Y23.41 +X35.69 Y22.3 +X34.97 Y21.83 +X34.75 Y21.62 +X34.53 Y21.42 +X34.45 Y21.31 +X34.45 Y21.21 +X34.52 Y21.18 +X34.59 Y21.16 +X34.81 Y21.29 +X35.04 Y21.42 +X35.12 Y21.42 +X35.19 Y21.42 +X35.26 Y21.37 +X35.33 Y21.33 +X35.15 Y21.07 +X34.97 Y20.81 +X34.85 Y20.56 +X34.68 Y20.27 +X34.57 Y20.11 +X34.45 Y19.95 +X34.45 Y19.86 +X34.51 Y19.78 +X34.56 Y19.78 +X34.7 Y19.87 +X34.84 Y19.96 +X35.19 Y20.26 +X35.54 Y20.57 +X36.26 Y21.22 +X36.66 Y21.54 +X36.7 Y21.51 +X36.7 Y21.2 +X36.7 Y20.89 +X36.83 Y20.78 +X36.96 Y20.66 +X36.87 Y20.5 +X36.78 Y20.34 +X36.92 Y20.25 +X37.05 Y20.3 +X37.09 Y20.11 +X37.14 Y19.77 +X37.27 Y19.67 +X37.41 Y19.57 +X37.51 Y19.62 +X37.61 Y19.67 +X37.78 Y20.37 +X37.92 Y20.79 +X38.11 Y21.01 +X38.14 Y21.01 +X38.18 Y20.91 +X38.36 Y20.54 +X38.64 Y19.9 +X38.76 Y19.63 +X38.95 Y19.19 +X39.06 Y18.92 +X39.18 Y18.66 +X39.26 Y18.67 +X39.33 Y18.69 +X39.31 Y18.94 +X39.3 Y19.12 +X39.3 Y19.3 +X39.3 Y19.63 +X39.31 Y19.96 +X39.26 Y20.32 +X39.2 Y20.73 +X39.51 Y20.38 +X39.83 Y20.04 +X39.95 Y20.04 +X40.08 Y20.04 +X40.08 Y20.09 +X40.08 Y20.14 +X39.97 Y20.32 +X39.87 Y20.5 +X39.87 Y20.64 +X39.64 Y20.98 +X39.4 Y21.32 +X39.3 Y21.66 +X39.15 Y22.06 +X39.05 Y22.56 +X39 Y23.02 +X39.16 Y24.05 +X39.47 Y25.64 +X39.63 Y26.5 +X39.67 Y26.73 +X39.72 Y26.76 +X39.77 Y26.79 +X39.8 Y26.66 +X39.92 Y26.53 +X40.01 Y26.53 +X40.01 Y26.71 +X39.97 Y26.89 +X39.94 Y26.96 +X39.88 Y27.11 +X39.84 Y27.25 +X40.02 Y27.62 +X40.18 Y28.02 +X40.47 Y28.69 +X40.76 Y29.37 +X40.91 Y29.67 +X41.27 Y30.39 +X41.57 Y30.97 +X41.86 Y31.55 +X41.89 Y31.43 +X41.91 Y31.31 +X41.96 Y30.97 +X42.02 Y30.64 +X42.27 Y30.13 +X42.4 Y29.98 +X42.52 Y29.83 +X42.62 Y29.88 +X42.71 Y29.94 +X42.81 Y30.14 +X42.91 Y30.34 +X42.92 Y28.45 +X42.93 Y26.56 +X42.81 Y25.1 +X42.68 Y23.65 +X42.58 Y23.28 +X42.58 Y22.69 +X42.74 Y21.92 +X42.98 Y21.09 +X43.2 Y20.63 +X43.42 Y20.26 +X43.67 Y19.95 +X43.92 Y19.64 +X44.03 Y19.61 +X44.13 Y19.58 +X44.17 Y19.6 +X44.2 Y19.63 +X44.29 Y19.92 +X44.38 Y20.22 +X44.57 Y20.68 +X44.67 Y21.14 +X44.7 Y21.57 +X44.74 Y22.01 +X44.83 Y22.57 +X44.86 Y22.91 +X44.81 Y23.44 +X44.7 Y23.9 +X44.67 Y24.15 +X44.63 Y24.26 +X44.58 Y24.36 +X44.53 Y24.61 +X44.42 Y25.12 +X44.29 Y25.71 +X44.17 Y26.3 +X44.07 Y26.86 +X43.99 Y27.45 +X43.92 Y28.04 +X43.88 Y28.68 +X43.85 Y29.32 +X44.09 Y29 +X44.17 Y28.93 +X44.37 Y28.76 +X44.49 Y28.68 +X44.61 Y28.68 +X44.72 Y28.68 +X44.75 Y28.72 +X44.77 Y28.75 +X44.8 Y29.06 +X44.84 Y29.36 +X44.86 Y29.4 +X44.88 Y30.01 +X44.89 Y30.59 +X44.85 Y30.95 +X44.78 Y31.31 +X44.59 Y31.68 +X44.4 Y32.06 +X44.05 Y32.89 +X43.95 Y33.56 +X43.87 Y34.53 +X43.84 Y35.19 +X43.98 Y35.81 +X44.23 Y36 +X44.43 Y36.22 +X44.61 Y36.57 +X44.78 Y36.92 +X44.78 Y37.24 +X44.96 Y37.43 +X45.16 Y37.62 +X45.63 Y37.98 +X46.08 Y38.34 +X46.88 Y38.7 +X47.3 Y38.7 +X47.72 Y38.7 +X47.89 Y38.65 +X48.06 Y38.6 +X48.2 Y38.45 +X48.35 Y38.3 +X48.32 Y38.17 +X48.29 Y38.03 +X48.42 Y38.03 +X48.54 Y38.03 +X48.73 Y38.09 +X48.92 Y38.14 +X48.92 Y38.22 +X48.92 Y38.3 +X49.18 Y38.26 +X49.43 Y38.23 +X49.7 Y38.16 +X49.96 Y38.09 +X50.04 Y38 +X50.12 Y37.92 +X50.06 Y37.89 +X50 Y37.87 +X49.8 Y37.7 +X49.55 Y37.52 +X49.48 Y37.44 +X49.48 Y37.37 +X49.56 Y37.37 +X49.83 Y37.49 +X50.02 Y37.61 +X50.18 Y37.66 +X50.35 Y37.72 +X50.37 Y37.73 +X50.38 Y37.79 +X50.53 Y37.84 +X50.68 Y37.88 +X50.91 Y37.85 +X51.14 Y37.82 +X51.7 Y37.7 +X52.26 Y37.57 +X52.3 Y37.57 +X52.34 Y37.57 +X52.34 Y38.33 +X51.96 Y38.4 +X51.04 Y38.7 +X50.71 Y39.02 +X50.57 Y38.84 +X49.91 Y38.88 +X49.35 Y39.26 +X45.25 Y39.26 +X44.85 Y39.18 +X44.45 Y39.1 +X44.24 Y39.1 +X44.03 Y39.1 +X43.91 Y39.02 +X43.76 Y38.9 +X43.48 Y38.76 +X43.23 Y38.64 +X43.08 Y38.53 +X42.94 Y38.41 +X42.67 Y38.15 +X42.41 Y37.88 +X42.3 Y37.88 +X42.3 Y37.88 +X42.02 Y37.72 +X41.74 Y37.59 +X41.64 Y37.59 +X41.52 Y37.62 +X41.34 Y37.75 +X41.15 Y37.87 +X41.12 Y37.82 +X41.25 Y37.62 +X41.42 Y37.47 +X41.59 Y37.42 +X41.86 Y37.42 +X41.94 Y37.44 +X41.87 Y37.35 +X41.71 Y37.12 +X41.46 Y36.61 +X41.2 Y36 +X41.03 Y35.19 +X40.85 Y34.48 +X40.69 Y34.12 +X40.19 Y33.63 +X39.69 Y33.14 +X38.77 Y32.38 +X38.71 Y32.33 +X38.64 Y32.28 +X38.47 Y32.13 +X38.17 Y31.92 +X38.03 Y31.81 +X37.82 Y31.64 +X37.61 Y31.48 +X37.07 Y31.43 +X36.52 Y31.39 +X35.63 Y31.31 +X34.73 Y31.2 +X34.5 Y31.17 +X33.9 Y31.1 +X33.52 Y31.06 +X33.55 Y31.44 +X33.64 Y32.01 +X33.7 Y32.51 +X33.71 Y32.82 +X34.08 Y33.19 +X34.44 Y33.56 +X34.94 Y34.01 +X35.42 Y34.45 +X35.9 Y34.89 +X36.23 Y35.19 +X36.83 Y35.72 +X37.34 Y36.08 +X37.85 Y36.45 +X38.34 Y36.78 +X38.83 Y37.11 +X39.61 Y37.62 +X40.12 Y37.93 +X41.02 Y38.47 +X41.38 Y38.66 +X42.4 Y39.26 +X40.76 Y39.26 +X40.28 Y38.95 +G0 Z5 + +G0 X44.02 Y38.18 Z5 +G1 F100 Z0 +X44.02 Y38.18 +X43.93 Y38.01 +X43.7 Y37.43 +X43.45 Y37.2 +X43.45 Y37.55 +X43.65 Y37.95 +X43.65 Y38.12 +X43.82 Y38.26 +X44.04 Y38.38 +X44.11 Y38.36 +X44.02 Y38.18 +G0 Z5 + +G0 X40.52 Y32.28 Z5 +G1 F100 Z0 +X40.52 Y32.28 +X40.54 Y32.12 +X40.7 Y31.9 +X40.93 Y31.9 +X41.22 Y32.12 +X41.19 Y32.07 +X41.17 Y32.03 +X39.57 Y28.78 +X39.52 Y28.78 +X39.41 Y29.21 +X39.37 Y29.62 +X39.32 Y29.88 +X39.15 Y30.37 +X40.43 Y32.36 +X40.49 Y32.36 +X40.52 Y32.28 +G0 Z5 + +G0 M5 X0 Y0 Z5 diff --git a/programs/other/cnc_editor/objects.png b/programs/other/cnc_editor/objects.png new file mode 100644 index 0000000000000000000000000000000000000000..58f7a53358ed3beb7942e1a89d0e3f1a25cd4a75 GIT binary patch literal 975 zcmV;=12FuFP)<{98FWQhbW?9;ba!ELWdLwtX>N2bZe?^J zG%heMGBNQWX_Wu~158OoK~zXf?UG+eQ*ji>??akJ4}n1s&Y+MD4D1g{LK3Au1hwc% zdeJgeQj1bEH>f$3#DAz*_$P4wLB*-~r?yC?o^xjNL9F+lWa$3gySrf9>HFKgZM#Eq z=4)RLV>{=3&iUSR$I(8e079XV&1QR6SEou(PfJUyt*u>ISwT`RhZO}-KzVg~Vr|yE zHfI(^zb~wfPak6$8IZcYJl~Y9Y0J;)x}C@Se1ahOL~*uJ|Dn4j!Z1MUc6+_NDC#p# zHeS*+U%lY-`vnneevQ>s%ov|b~Uw=B)crN4Bl`O&U2NMj1)M~X1;DUi*aL4JyIeszdGmPC3Z~;m z?&|coMx&7d+#4Gm4#$qmh3?14m^WA08=l9Ib*4G@ylrx{Az}$9!p3c<)9LY6Bym+K z3U76)<1aE#eHk;YM;;pY`f2})E1`SGC>Aa;O2!010}RUlJtFVAU5^}V&gv$SKBoX1|%3VurD1LxMPiv zI4OV!!?ZL^mOh&Ap@r9E?W5&kDjAWhlA=IoxOJ+9MqiRi$70k#Q>`qCQbaOvZ;%xx znrNV!x=X3Oh}w&(yNm{ESkltZ8YD4*d&8WVTj*^K>ub=GE}!%TWYkheF-v04@(62- z0vHbi7>VwuIaHQO<(X8S!x$t{!t*GAg&t-a<1rhpg(p~)pCw%ZOPciT1_}UY8Pri* z5d$#3F!c|R&j6G#Q2|(b*>So`so@qqxhz|PH#o!%US(lB?>_IP4vE(#v7@>n(YDBhO?Hk5lCV@8YIa8)H%Y8VGq0w*0X>U{6un>7bmF% xe~lrw3O7JtFq|M6D+K_>{qqoUiU;-((QoTSP(A8QCprKC002ovPDHLkV1n+bvjG4A literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/tl_sys_16.png b/programs/other/cnc_editor/tl_sys_16.png new file mode 100644 index 0000000000000000000000000000000000000000..65fac3ba12531b6c908b82d8a509744468817157 GIT binary patch literal 1425 zcmV;C1#bF@P)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11nNmd zK~!i%?V4RkR6!Jg#~#$S4Sh2z%C`g|kzRb;0$+?05yBp%G7T|^1T6@}-FoPUtlfSL zlJE)z;m=bP5*b#~9}-(e^=M(?Lq!ltglnfcv(9zy+_`sVQ!DJ=<*=9CIo~~J?#!7p z=iV%!2bs@-fcYFmr#wD64pA!#iGc)6r>0%awE$Em2MH`cyc{apD_jsWfJK0$2!x^` z7sLj9`~D3&dOMi8qC^fxfFJ-r3WyEZcYYsaAIVNPmSu7lAV9Vs+s^vK2IN)e0r?;_ zOkY#|p_Y)%X;mAr@xVqP4-Elhv_H0moPZmTZa_{&4kNo{PykcqaCI0)#zvd~ukpZc zBkx2>+2Mi~pinjfSc4XG34P{fix<-lB;8Q|2LUlQK+=*v_di@M0szc*T+oTZKnf<) zg2#g|G(Q-oYr_+oAIzBK2eJjIY|;GS>LCJsba|H{+K`5TVY)KS&;_+G>V{|m7R?V3 zfb&BI@dYFYH!$TdG(X@Ij6(*FtxzwnVjloRY();>mhh18Yk?Qw9bIToZp+tO5U18xB-cT}%}cV78{>NfIDl$DjsyB9#EYy?Qs`~acoGdJ5eKUna&5UkEiB16G= zAj^}1a{xbo>L=5)n|UlA$a1M}8Qkt{(gOh2E91e}j|5It8U++JU~GuMrMg1B1)Y1c z*+i1%?2deR|K_P45M-)UoIIRV!Tvk>F zkw^p@8X8;>BS2ME6|}dvLwR|*3t|JNrlz2)tBaW{N=;1-ARrctDIqqXt*wojiH&7x zZEa-$5z^S$=$uTYrKQl)(qcE{3aW2(r?60(&XtvwP+wnf1ZZk%g5u(0rv*bpLr_#y z#K^ML*4El!R4yqgfzi=Xbv%%7GbY>|ax?Ta=P2_6o+n({ABJ0ry=uVe zs+I70VlF!u_X+&`>n8#yw&vb~U_xabFJz@`JyX z9|T*TMJNZVV#2H8KC}G-Zn{mErO*@u`(^ePRzKTDE9%cCtjn^8++;VMr}P&1(>TRhFlQW zNR;yfcRkSwaRF5MfxDg3Ji!KwMaOe&DVrhUZgH zoKse&`~LMrr?L@XuAUeQ>WLnaMq69gMJO#G<9Oipe8D&#cnzd`X<0BF zrTb?pcw~T`PRw3jPd0^cnqTR~0Pa{UP^>?VRW{`koX3c+UF+ zzeSfE0DeW?_u>HJ1qIABE{R-Pp_p|8&&B_+EkAt6!Joa2@<@|!W5y#<>=V)F|0y1r z#>S--6D?~JqEY%frGa2u*IXdv9(@CD+)QX&H6TVOpouIBpkU2oI(w-b27+z1@!)?P fNTxn7ctH6DrSWz3H&)?m00000NkvXXu0mjf76N={ literal 0 HcmV?d00001 diff --git a/programs/other/cnc_editor/toolbar.png b/programs/other/cnc_editor/toolbar.png new file mode 100644 index 0000000000000000000000000000000000000000..a7979ca2cd10912a169c8856c70b4939a48b0264 GIT binary patch literal 3095 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 l4T-j7B@GD pointer to object node + mov edi,[ebx+Object.FigData] + + mov esi,txt_00 + stdcall FigureInit,FigData,edi + add edi,4 + mov esi,txt_01 + stdcall FigureInit,FigData,edi + add edi,4 + mov esi,txt_02 + stdcall FigureInit,FigData,edi + add edi,4 + mov esi,txt_03 + stdcall FigureInit,FigData,edi + add edi,4 + mov esi,txt_04 ;X__ Y__ + stdcall FigureInit,FigData,edi + ; *** create new points *** + mov edx,[edi] + cmp [opt_gr1],opt1 + jne .rect + ;circle + fld qword[NOptCoordY1] + fistp dword[edx+Figure.PoiCount] + inc dword[edx+Figure.PoiCount] + mov eax,[edx+Figure.PoiCount] + imul eax,sizeof.Point + stdcall mem.ReAlloc,[edx+Figure.PoiData],eax + mov [edx+Figure.PoiData],eax + + ;init points + fldpi + fadd st0,st0 + fdiv qword[NOptCoordY1] + fldz + ;st0 - angle (=0) + ;st1 - delta angle (=pi/slices) + + mov ecx,[edx+Figure.PoiCount] + cmp ecx,3 + jge @f + mov ecx,3 + @@: + mov edx,[edx+Figure.PoiData] + add edx,Point.CoordX + .cycle0: + add edx,sizeof.Point + fadd st0,st1 ;angle += delta angle + + fld st0 + fcos + fmul qword[NOptCoordX1] ;st0 = cos(angle) * radius + fadd qword[NOptCoordX0] + fstp qword[edx] + fld st0 + fsin + fmul qword[NOptCoordX1] ;st0 = sin(angle) * radius + fadd qword[NOptCoordY0] + fstp qword[edx+8] + loop .cycle0 + ffree st0 + fincstp + ffree st0 + fincstp + jmp .end0 + .rect: + ;rect + mov eax,5 + mov dword[edx+Figure.PoiCount],eax + imul eax,sizeof.Point + stdcall mem.ReAlloc,[edx+Figure.PoiData],eax + mov [edx+Figure.PoiData],eax + ;init points + push edi + mov ecx,[edx+Figure.PoiData] + ;p1 + add ecx,sizeof.Point + lea edi,[ecx+Point.CoordX] + mov esi,NOptCoordX1 + movsd + movsd + mov esi,NOptCoordY0 + movsd + movsd + ;p2 + add ecx,sizeof.Point + lea edi,[ecx+Point.CoordX] + mov esi,NOptCoordX1 + movsd + movsd + mov esi,NOptCoordY1 + movsd + movsd + ;p3 + add ecx,sizeof.Point + lea edi,[ecx+Point.CoordX] + mov esi,NOptCoordX0 + movsd + movsd + mov esi,NOptCoordY1 + movsd + movsd + ;p4 + add ecx,sizeof.Point + lea edi,[ecx+Point.CoordX] + mov esi,NOptCoordX0 + movsd + movsd + mov esi,NOptCoordY0 + movsd + movsd + pop edi + .end0: + stdcall found_parent_obj,[edi] ;get figure number in ecx + stdcall figure_update_coords,ObjData,ecx + + add edi,4 + mov esi,txt_05 + stdcall FigureInit,FigData,edi + add edi,4 + mov esi,txt_06 + stdcall FigureInit,FigData,edi + + stdcall ObjCalculateScale,ebx +popad + ret +endp + +align 4 +proc get_n_file_opt uses eax + ;загрузка координат в editbox-ы + mov word[NumberSymbolsAD],3 + finit + fld qword[NOptCoordX0] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit4, Data_String + fld qword[NOptCoordY0] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit5, Data_String + fld qword[NOptCoordX1] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit6, Data_String + fld qword[NOptCoordY1] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit7, Data_String + fld qword[NOptCoordZ0] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit8, Data_String + fld qword[NOptCoordZ1] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit9, Data_String + ; + ;stdcall [edit_box_draw], edit4 + ;stdcall [edit_box_draw], edit5 + ret +endp + +align 4 +proc timer_funct_n_file uses eax + ;просматриваем выделенную координату + mov eax,[opt_gr1] + cmp eax,[last_opt] + je @f + mov eax,[opt_gr1] + mov [last_opt],eax + call red_win_n_file + @@: + ret +endp + +capt_coord_x0 db 'X0:',0 +capt_coord_y0 db 'Y0:',0 +capt_coord_z0 db 'Z0:',0 +capt_coord_x1 db 'X1:',0 +capt_coord_y1 db 'Y1:',0 +capt_coord_z1 db 'Z1:',0 +capt_coord_r db 'R:',0 +capt_coord_s db 'S:',0 + +edit4 edit_box 80, 24, 28, 0xffd0d0, 0xff, 0x80ff, 0, 0x8000, 34, string4, mouse_dd, 0 +edit5 edit_box 80, 24, 46, 0xd0d0ff, 0xff, 0x80ff, 0, 0x8000, 34, string5, mouse_dd, 0 +edit6 edit_box 80, 24, 64, 0xffd0d0, 0xff, 0x80ff, 0, 0x8000, 34, string6, mouse_dd, 0 +edit7 edit_box 80, 24, 82, 0xd0d0ff, 0xff, 0x80ff, 0, 0x8000, 34, string7, mouse_dd, 0 +edit8 edit_box 80, 24, 100, 0xffd0d0, 0xff, 0x80ff, 0, 0x8000, 34, string8, mouse_dd, 0 +edit9 edit_box 80, 24, 118, 0xd0d0ff, 0xff, 0x80ff, 0, 0x8000, 34, string9, mouse_dd, 0 +editboxes_end_nf: + +string4 rb 34 +string5 rb 34 +string6 rb 34 +string7 rb 34 +string8 rb 34 +string9 rb 34 + +align 4 +last_opt dd opt1 ;for timer +opt_gr1 dd opt1 + +opt1 option_box opt_gr1, 115,28,6,12,0xd0d0ff, 0xff, 0x80ff,txt_circle,txt_circle.end-txt_circle +opt2 option_box opt_gr1, 115,46,6,12,0xd0d0ff, 0xff, 0x80ff,txt_rect,txt_rect.end-txt_rect + +align 4 +opt_grlist1 dd opt1,opt2,0 ;end option group + +txt_00 db ';PCB graving',0 +txt_01: db 'G0 M3 X0 Y0 Z' +.z: rb 12 +txt_02: db 'G0 X' +.x: rb 50 ;X__ Y__ Z__ +txt_03: db 'G1 F100 Z' +.z: rb 12 +txt_04: db 'X' +.x: rb 30 ;X__ Y__ +txt_05: db 'G0 Z' +.z: rb 12 +txt_06: db 'G0 M5 X0 Y0 Z' +.z: rb 12 + +if lang eq ru +capt_n_file db 'Создать новый файл',0 +capt_sel_fig db 'Выберите фигуру:',0 +txt_circle: db 'Окружность' +.end: db 0 +txt_rect: db 'Прямоугольник' +.end: db 0 +else +capt_n_file db 'Create new file',0 +capt_sel_fig db 'Select figure:',0 +txt_circle: db 'Circle' +.end: db 0 +txt_rect: db 'Rectangle' +.end: db 0 +end if \ No newline at end of file diff --git a/programs/other/cnc_editor/wnd_point_coords.inc b/programs/other/cnc_editor/wnd_point_coords.inc new file mode 100644 index 0000000000..de8d410862 --- /dev/null +++ b/programs/other/cnc_editor/wnd_point_coords.inc @@ -0,0 +1,302 @@ +; +; в этом файле собраны функции нужные для создания и +; работы окна с координатами вершин +; + +wnd_prop_width equ 320 ;ширина окна со свойствами объекта +wnd_prop_height equ 150 ;высота окна со свойствами объекта + +align 4 +wnd_run_prop db 0 ;переменная следящая за тем что-бы не запускать больше 1-го окна со свойствами одновременно +txt_p db '.',0 + +align 4 +wnd_pObj dd 0 ;obj +wnd_pFig dd 0 ;фигура +wnd_FigN dd 0 ;fig number +wnd_pPoi dd 0 ;select point +wnd_PoiN dd 0 ;select point number + + +;даное окно (процесс) вызываеться функцией but_wnd_coords +align 4 +start_prop: +pushad + mcall SF_SET_EVENTS_MASK,0x27 ;маска ожидаемых событий + inc byte[wnd_run_prop] + + ;имя объекта + stdcall mem_copy,capt_p,txt_obj,1+txt_obj.end-txt_obj + mov edi,capt_p+txt_obj.end-txt_obj + mov eax,[wnd_pObj] + or eax,eax + jz @f + add eax,Object.Caption + stdcall str_cat,edi,eax + @@: + stdcall str_cat,edi,txt_39 + ;имя фигуры + mov edi,capt_fig.name + mov byte[edi],0 ;clear pervios name + mov eax,[wnd_pFig] + or eax,eax + jz @f + add eax,Figure.Caption + stdcall str_cat,edi,eax + @@: + stdcall str_cat,edi,txt_39 + ;номер точки + mov edi,capt_poi.numb + mov byte[edi],0 + mov eax,[wnd_PoiN] + stdcall convert_int_to_str, 20 + + edit_boxes_set_sys_color edit1,editboxes_end,sc ;установка системных цветов + init_checkboxes2 check_boxes,check_boxes_end + check_boxes_set_sys_color2 check_boxes,check_boxes_end,sc + call get_point_coords +popad + call red_win_prop + +;не отрывать эту функцию от предыдущей +align 4 +still_prop: + pushad + + mcall SF_WAIT_EVENT_TIMEOUT,10 + or eax,eax + jnz @f + call timer_funct_prop + jmp .end + @@: + + cmp al,1 ;изм. положение окна + jne @f + call red_win_prop + jmp .end + @@: + cmp al,2 + jne @f + call key_prop + jmp .end + @@: + cmp al,3 + jz button_prop + cmp al,6 + jne @f + call mouse_prop + @@: +.end: + popad + jmp still_prop + +align 4 +red_win_prop: +pushad + mcall SF_REDRAW,SSF_BEGIN_DRAW + + mcall SF_STYLE_SETTINGS,SSF_GET_SKIN_HEIGHT + mov edi,capt_p ;children window caption + mov bx,word[procinfo.box.left] + add bx,word[buf_0.l] + add bx,5 ;ширина боковой рамки + shl ebx,16 + mov bx,wnd_prop_width + mov cx,word[procinfo.box.top] + add cx,ax ;add skin height + add cx,word[buf_0.t] + shl ecx,16 + mov cx,wnd_prop_height + mov edx,[sc.work] + or edx,0x33000000 + xor eax,eax + int 0x40 + + mov esi,[sc.work_button] + ;ebx = (l<:)+w, ecx = (t<:)+h + mcall SF_DEFINE_BUTTON, (5 shl 16)+59, (95 shl 16)+20, 3 + mcall , (75 shl 16)+59, (95 shl 16)+20, 4 + + mov ecx,[sc.work_text] + bts ecx,31 ;рисуемая строка заканчивается нулём + mcall SF_DRAW_TEXT, (5 shl 16)+5,, capt_fig + mcall , (5 shl 16)+15,, capt_poi + + mcall , (5 shl 16)+32,, capt_coord_x + mcall , (5 shl 16)+50,, capt_coord_y + + mov ecx,[sc.work_button_text] + bts ecx,31 + mcall , (9 shl 16)+101,, txt_but_cancel + mov edx,txt_but_apply + cmp dword[wnd_pPoi],0 + jne @f + mov edx,txt_but_create + @@: + mcall ,(79 shl 16)+101 + + stdcall [edit_box_draw], edit1 + stdcall [edit_box_draw], edit2 + checkboxes_draw2 check_boxes,check_boxes_end + + mcall SF_REDRAW,SSF_END_DRAW +popad + ret + +align 4 +proc key_prop uses eax ebx + mcall SF_GET_KEY + + test word [edit1.flags],10b ;ed_focus + je @f + stdcall [edit_box_key], edit1 + jmp .end + @@: + test word [edit2.flags],10b + je @f + stdcall [edit_box_key], edit2 + ;jmp .end + @@: + + .end: + ret +endp + +align 4 +mouse_prop: + stdcall [edit_box_mouse], edit1 + stdcall [edit_box_mouse], edit2 + checkboxes_mouse2 check_boxes,check_boxes_end + ret + +align 4 +button_prop: + mcall SF_GET_BUTTON + + cmp ah,3 + je .exit + cmp ah,4 + jne .end_save + push eax ebx ecx edi esi + mov ebx,[wnd_pPoi] + or ebx,ebx + jnz .select_1 + ; *** create new point *** + mov ebx,[wnd_pFig] + mov eax,[ebx+Figure.PoiCount] + inc eax + imul eax,sizeof.Point + stdcall mem.ReAlloc,[ebx+Figure.PoiData],eax + mov [ebx+Figure.PoiData],eax + inc dword[ebx+Figure.PoiCount] + mov ebx,[ebx+Figure.PoiCount] + dec ebx + imul ebx,sizeof.Point + add ebx,eax + .select_1: + finit + + mov esi,string1 + mov edi,Data_String + cld + mov ecx,8 + rep movsd + call String_to_DoubleFloat + fld qword[Data_Double] ;считываем как double + fstp qword[ebx+Point.CoordX] ;сохраняем как double + + mov esi,string2 + mov edi,Data_String + cld + mov ecx,8 + rep movsd + call String_to_DoubleFloat + fld qword[Data_Double] + fstp qword[ebx+Point.CoordY] + + stdcall figure_update_coords,[wnd_pObj],[wnd_FigN] + ;выставляем свойства + and dword[ebx+Point.Prop], not 7 ;7 = 2^PROP_BIT_START +2^PROP_BIT_LINE +2^PROP_BIT_LINE_CLOSE) + mov dword[offs_last_timer],0 ;для обновления блока в таймере + pop esi edi ecx ebx eax + jmp .exit + .end_save: + + cmp ah,1 + jne still_prop.end +.exit: + mov byte[wnd_run_prop],0 ;обнуляем счетчик окон + mcall SF_TERMINATE_PROCESS ;выход из программы + +align 4 +proc get_point_coords uses eax ebx + ;загрузка координат в editbox-ы + mov ebx,[wnd_pPoi] + btr dword[ch1.flags],1 + btr dword[ch2.flags],1 + btr dword[ch3.flags],1 + or ebx,ebx + jz .end0 + mov word[NumberSymbolsAD],8 + finit + fld qword[ebx+Point.CoordX] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit1, Data_String + fld qword[ebx+Point.CoordY] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit2, Data_String + ; + jmp .end1 + .end0: + stdcall [edit_box_set_text], edit1, txt_p + stdcall [edit_box_set_text], edit2, txt_p + .end1: + ;stdcall [edit_box_draw], edit1 + ;stdcall [edit_box_draw], edit2 + ret +endp + +align 4 +proc timer_funct_prop + ;просматриваем выделенную координату + ret +endp + +align 4 +capt_p rb 64 +if lang eq ru +capt_fig: db 'Команда: ',39 +.name: rb 55 +capt_poi: db 'Точка: ' +.numb: rb 25 +else +capt_fig: db 'Command: ',39 +.name: rb 55 +capt_poi: db 'Point: ' +.numb: rb 25 +end if + +capt_coord_x db 'X:',0 +capt_coord_y db 'Y:',0 + +edit1 edit_box 80, 18, 28, 0xffd0d0, 0xff, 0x80ff, 0, 0x8000, 34, string1, mouse_dd, 0 +edit2 edit_box 80, 18, 46, 0xd0d0ff, 0xff, 0x80ff, 0, 0x8000, 34, string2, mouse_dd, 0 +editboxes_end: + +string1 rb 34 +string2 rb 34 + +check_boxes: +ch1 check_box2 (115 shl 16+15),(28 shl 16 +11),5,0xffffff,0,0x80000000,ch_text.1,ch_flag_en+ch_flag_middle +ch2 check_box2 (115 shl 16+15),(43 shl 16 +11),5,0xffffff,0,0x80000000,ch_text.2,ch_flag_en+ch_flag_middle +ch3 check_box2 (115 shl 16+15),(58 shl 16 +11),5,0xffffff,0,0x80000000,ch_text.3,ch_flag_en+ch_flag_middle +check_boxes_end: + +ch_text: +.1 db 'X',0 +.2 db 'Y',0 +.3 db 'Z',0 diff --git a/programs/other/cnc_editor/wnd_scale.inc b/programs/other/cnc_editor/wnd_scale.inc new file mode 100644 index 0000000000..88ccdc6ae0 --- /dev/null +++ b/programs/other/cnc_editor/wnd_scale.inc @@ -0,0 +1,181 @@ +; +; в этом файле собраны функции нужные для создания и +; работы окна с настройками +; + +wnd_scale_width equ 320 ;ширина окна с настройками +wnd_scale_height equ 150 ;высота окна с настройками + +align 4 +wnd_run_scale db 0 ;переменная следящая за тем что-бы не запускать больше 1-го окна со свойствами одновременно + +;даное окно (процесс) вызываеться функцией but_wnd_coords +align 4 +start_scale: +pushad + mcall SF_SET_EVENTS_MASK,0x27 ;маска ожидаемых событий + inc byte[wnd_run_scale] + + edit_boxes_set_sys_color edit3,editboxes_end_sc,sc ;установка системных цветов + call get_scale +popad + call red_win_scale + +;не отрывать эту функцию от предыдущей +align 4 +still_scale: + pushad + + mcall SF_WAIT_EVENT_TIMEOUT,10 + or eax,eax + jnz @f + call timer_funct_scale + jmp .end + @@: + + cmp al,1 ;изм. положение окна + jne @f + call red_win_scale + jmp .end + @@: + cmp al,2 + jne @f + call key_scale + jmp .end + @@: + cmp al,3 + jz button_scale + cmp al,6 + jne @f + call mouse_scale + @@: +.end: + popad + jmp still_scale + +align 4 +red_win_scale: +pushad + mcall SF_REDRAW,SSF_BEGIN_DRAW + + mcall SF_STYLE_SETTINGS,SSF_GET_SKIN_HEIGHT + mov edi,capt_opt ;children window caption + mov bx,word[procinfo.box.left] + add bx,word[buf_0.l] + add bx,5 ;ширина боковой рамки + shl ebx,16 + mov bx,wnd_scale_width + mov cx,word[procinfo.box.top] + add cx,ax ;add skin height + add cx,word[buf_0.t] + shl ecx,16 + mov cx,wnd_scale_height + mov edx,[sc.work] + or edx,0x33000000 + xor eax,eax + int 0x40 + + mov esi,[sc.work_button] + ;ebx = (l<:)+w, ecx = (t<:)+h + mcall SF_DEFINE_BUTTON, (5 shl 16)+59, (95 shl 16)+20, 3 + mcall , (75 shl 16)+59, (95 shl 16)+20, 4 + + mov ecx,[sc.work_text] + bts ecx,31 ;рисуемая строка заканчивается нулём + mcall SF_DRAW_TEXT, (5 shl 16)+15,, capt_sc + + mov ecx,[sc.work_button_text] + bts ecx,31 + mcall , (9 shl 16)+101,, txt_but_cancel + mov edx,txt_but_apply + mcall ,(79 shl 16)+101 + + stdcall [edit_box_draw], edit3 + + mcall SF_REDRAW,SSF_END_DRAW +popad + ret + +align 4 +proc key_scale uses eax ebx + mcall SF_GET_KEY + + test word [edit3.flags],10b ;ed_focus + je @f + stdcall [edit_box_key], edit3 + ;jmp .end + @@: + + .end: + ret +endp + +align 4 +mouse_scale: + stdcall [edit_box_mouse], edit3 + ret + +align 4 +button_scale: + mcall SF_GET_BUTTON + + cmp ah,3 + je .exit + cmp ah,4 + jne .end_save + push eax ecx edi esi + finit + + mov esi,string3 + mov edi,Data_String + cld + mov ecx,8 + rep movsd + call String_to_DoubleFloat + fld qword[Data_Double] ;считываем как double + fstp qword[Scale1mm] ;сохраняем как double + + pop esi edi ecx eax + jmp .exit + .end_save: + + cmp ah,1 + jne still_scale.end +.exit: + mov byte[wnd_run_scale],0 ;обнуляем счетчик окон + mcall SF_TERMINATE_PROCESS ;выход из программы + +align 4 +get_scale: + ;загрузка координат в editbox-ы + push eax + mov word[NumberSymbolsAD],8 + finit + fld qword[Scale1mm] + fstp qword[Data_Double] + call DoubleFloat_to_String + call String_crop_0 + stdcall [edit_box_set_text], edit3, Data_String + ;stdcall [edit_box_draw], edit3 + pop eax + ret + +align 4 +proc timer_funct_scale + ;просматриваем выделенную координату + ret +endp + +align 4 +if lang eq ru +capt_opt db 'Настройки',0 +capt_sc db 'Масштаб:',0 +else +capt_opt db 'Options',0 +capt_sc db 'Scale:',0 +end if + +edit3 edit_box 80, 54, 11, 0xffd0d0, 0xff, 0x80ff, 0, 0x8000, 34, string3, mouse_dd, 0 +editboxes_end_sc: + +string3 rb 34