Subversion Repositories Kolibri OS

Rev

Rev 2487 | Rev 2507 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;
  2. ; функци для создания и редактирования проводов
  3. ;
  4.  
  5. ;--------------------------------------
  6. struct Cell
  7.         x dd ? ;+0
  8.         y dd ? ;+4
  9.         liv db ? ;+8
  10.         napr db ? ;+9
  11. ends
  12.  
  13. offs_cell_x equ 0
  14. offs_cell_y equ 4
  15. offs_cell_liv equ 8
  16. offs_cell_napr equ 9
  17.  
  18. ;структура для создания поля
  19. align 4
  20. pole:
  21. .index dd 0
  22. cell dd 0 ;указатель на память со структурами ячеек
  23. .max_cell dd 90000
  24. .b_sort dd 0 ;граница для сортированных ячеек
  25.  
  26. pole_index   equ dword[edi]
  27. pole_data     equ dword[edi +4] ;указатель на память со структурами ячеек
  28. pole_max_cell equ dword[edi +8]
  29. pole_b_sort   equ dword[edi+12] ;граница для сортированных ячеек
  30. offs_pole_b_sort equ 12
  31.  
  32. macro get_cell_offset reg,ind
  33. {
  34.         mov reg,ind
  35.         imul reg,sizeof.Cell
  36.         add reg,dword[cell]
  37. }
  38.  
  39. er_oom db 0 ;на случай исчерпания памяти
  40. Cor_x dd 0
  41. Cor_y dd 0
  42. zoom db 3 ;масштаб поля
  43. txt_zoom db 'Масштаб:',0
  44. txt_osob db 'Точек:',0
  45. txt_info: db 'Размер: '
  46. .size: rb 16
  47. txt_mull db '*',0
  48. txt_space db ' ',0
  49. txt_nl db 13,10,0
  50. txt_buf rb 32
  51.  
  52.  
  53. align 4
  54. proc pole_init uses eax ebx edi, pole:dword
  55.         mov edi,dword[pole]
  56.  
  57.         ;*** код с одной областью в памяти ***
  58.         mov ebx,4
  59.         add ebx,sizeof.Cell
  60.         imul ebx,pole_max_cell
  61.         stdcall mem.Alloc,ebx
  62.         mov pole_index,eax
  63.  
  64.         mov ebx,pole_max_cell
  65.         shl ebx,2
  66.         add eax,ebx
  67.         mov pole_data,eax
  68.  
  69.         stdcall pole_clear, edi
  70.         stdcall pole_paint, edi ;рисование поля в буфере (не на экране)
  71.         ret
  72. endp
  73.  
  74. align 4
  75. proc pole_delete uses edi, pole:dword
  76.         mov edi,dword[pole]
  77.         stdcall mem.Free,pole_index
  78.         ret
  79. endp
  80.  
  81. ;чистка проводов на схеме
  82. align 4
  83. proc pole_clear uses eax ecx edi, pole:dword
  84.         mov edi,dword[pole]
  85.  
  86.         xor eax,eax
  87.         mov pole_b_sort,eax
  88.         mov byte[er_oom],al
  89.         cld
  90.         mov ecx,pole_max_cell
  91.         imul ecx,sizeof.Cell
  92.         mov edi,pole_data
  93.         repne stosb ;memset(cell,0,sizeof(Cell)*pole_max_cell);
  94.  
  95.         mov edi,dword[pole]
  96.         mov ecx,pole_max_cell
  97.         mov edi,pole_index
  98.         @@:
  99.                 stosd ;for(i=0;i<pole_max_cell;i++) pole_index[i]=i;
  100.                 ;mov dword[edi],eax
  101.                 ;add edi,4
  102.                 inc eax
  103.                 loop @b
  104.         ret
  105. endp
  106.  
  107. align 4
  108. proc pole_cell_creat, pole:dword, x:dword, y:dword, li:dword
  109.         pushad
  110.         mov edi,dword[pole]
  111.         mov esi,pole_index
  112.  
  113.         ; *** если клетка уже была создана
  114.         stdcall pole_cell_find, [pole], [x],[y]
  115.         cmp eax,0
  116.         je @f
  117.                 get_cell_offset ebx,eax
  118.                 jmp .change
  119.         @@:
  120.  
  121.         ; *** создание новой ячейки
  122.         ; находим номер свободной ячейки (i) для добавления новой
  123.         ;mov esi,pole_index
  124.         inc dword[esi]
  125.         mov ebx,pole_max_cell
  126.         cmp dword[esi],ebx
  127.         jne @f
  128.                 dec dword[esi]
  129.                 ;... need call message: "eror out of memory" ...
  130.                 ;... вывод сообщения переполнения надо добавить  ...
  131.                 mov byte[er_oom],0
  132.                 jmp .fun_e ;return;
  133.         @@:
  134.         mov eax,dword[esi] ;eax - номер для последней ячейки
  135.         shl eax,2
  136.         add eax,pole_index ;eax - указатель на добавляемую ячейку (в конец массива)
  137.         get_cell_offset ebx,dword[eax]
  138.         mov ecx,dword[x]
  139.         mov dword[ebx],ecx ;+0 = .x
  140.         mov edx,dword[y]
  141.         mov dword[ebx+4],edx ;+4 = .y
  142.         .change:
  143.                 mov ecx,[li]
  144.                 mov byte[ebx+offs_cell_liv],cl
  145.         .fun_e:
  146.         popad
  147.         ret
  148. endp
  149.  
  150. ;удаление ячейки
  151. align 4
  152. proc pole_cell_delete, pole:dword, x:dword, y:dword
  153.         pushad
  154.         mov edi,dword[pole]
  155.         mov ebx,edi
  156.         add ebx,offs_pole_b_sort
  157.         mov esi,pole_index
  158.  
  159.         mov ecx,[esi]
  160.         cmp ecx,1
  161.         jl .fun_e
  162.  
  163.         stdcall pole_cell_find, [pole], [x],[y]
  164.         cmp eax,0
  165.         je .fun_e ;если клетка не была создана
  166.  
  167.         dec dword[esi]
  168.  
  169.         mov edi,esi
  170.         add edi,4
  171.         mov edx,ecx
  172.         cld
  173.         repnz scasd ;поиск
  174.         sub edi,4
  175.  
  176.         cmp dword[ebx],1 ;[ebx]=pole_b_sort
  177.         jl @f
  178.         mov eax,edi
  179.         sub eax,esi ;esi=pole_index
  180.         shr eax,2
  181.         dec eax
  182.         cmp [ebx],eax ;eax - позиция указателя удаляемой ячейки
  183.         jle @f ;было jl @f
  184.                 dec dword[ebx]
  185.         @@:
  186.  
  187.         shl edx,2
  188.         add edx,esi ;конечный элемент массива
  189.         sub edx,edi
  190.         shr edx,2
  191.         mov ecx,edx
  192.  
  193.         bt ecx,31
  194.         jc .fun_e
  195.                 mov esi,edi
  196.                 add esi,4
  197.                 mov edx,[edi] ;сохранение текущего указателя
  198.                 cld
  199.                 rep movsd
  200.                 mov [edi],edx ;восстановление текущего указателя (в конце массива)
  201.         .fun_e:
  202.         popad
  203.         ret
  204. endp
  205.  
  206. if debug
  207. align 4
  208. proc but_test_pole, pole:dword
  209.         pushad
  210.         stdcall [buf2d_clear], buf_0, [buf_0.color]
  211.  
  212.         mov edi,dword[pole]
  213.         stdcall pole_paint,edi
  214.         mov ebx,5
  215.  
  216.         mov esi,pole_index
  217.         mov ecx,[esi]
  218.  
  219.         mov eax,pole_b_sort
  220.         mov edi,open_file_lif
  221.         stdcall convert_int_to_str
  222.         stdcall [buf2d_draw_text], buf_0, buf_font,edi,5,ebx,color_s0 ;рисуем b_sort
  223.         add ebx,18
  224.  
  225.         mov eax,[esi]
  226.         add esi,4
  227.         stdcall convert_int_to_str
  228.         stdcall [buf2d_draw_text], buf_0, buf_font,edi,5,ebx,color_s0 ;рисуем число точек
  229.         add ebx,9
  230.  
  231.         cmp ecx,1
  232.         jl .end_dr
  233.         cld
  234.         @@:
  235.                 mov eax,[esi]
  236.                 add esi,4
  237.                 stdcall convert_int_to_str
  238.                 stdcall [buf2d_draw_text], buf_0, buf_font,edi,5,ebx,color_caption ;рисуем указатели на массивы точек
  239.                 add ebx,9
  240.                 loop @b
  241.         .end_dr:
  242.         mov ecx,4
  243.         cld
  244.         @@:
  245.                 mov eax,[esi]
  246.                 add esi,4
  247.                 stdcall convert_int_to_str
  248.                 stdcall [buf2d_draw_text], buf_0, buf_font,edi,5,ebx,color_border ;рисуем 4 строки указателей
  249.                 add ebx,9
  250.                 loop @b
  251.  
  252.         stdcall [buf2d_draw], buf_0
  253.  
  254.         ;call redraw_pole
  255.         popad
  256.         ret
  257. endp
  258. end if
  259.  
  260. ;output:
  261. ; eax - index
  262. align 4
  263. proc pole_cell_find uses edi, pole:dword, x:dword, y:dword
  264.         mov edi,dword[pole]
  265.  
  266.         mov eax,pole_index
  267.         cmp dword[eax],0
  268.         jne @f
  269.                 xor eax,eax ;if(!fristC) return 0;
  270.                 jmp .fun_e
  271.         @@:
  272.  
  273.         xor eax,eax ;fnd=0;
  274.         cmp pole_b_sort,0
  275.         je @f
  276.                 stdcall pole_bin_find, pole_index, [x],[y], pole_b_sort ;i=BinFind(pole_index, x,y, pole_b_sort);
  277.                 cmp eax,0
  278.                 je @f
  279.                         shl eax,2
  280.                         add eax,pole_index
  281.                         mov eax,dword[eax] ;if(i) fnd=pole_index[i];
  282.                         jmp .fun_e
  283.         @@:
  284.  
  285.         cmp eax,0
  286.         jne @f ;поиск ячейки за бинарным деревом
  287.                 push ebx ecx edx esi
  288.                 ;ebx -> i
  289.                 ;ecx -> firstC
  290.                 ;edx -> &pole_index[i]
  291.                 ;esi -> cell[pole_index[i]]
  292.                 mov ecx,pole_index
  293.                 mov ebx,pole_b_sort
  294.                 mov edx,ebx
  295.                 shl edx,2
  296.                 add edx,ecx
  297.                 mov ecx,dword[ecx]
  298.                 .cycle_b: ;for(i=pole_b_sort+1;i<=fristC;i++)
  299.                         inc ebx
  300.                         cmp ebx,ecx
  301.                         jg .not_found
  302.                         add edx,4
  303.                         get_cell_offset esi,dword[edx]
  304.                         mov eax,dword[x]
  305.                         cmp dword[esi],eax ;+0 = .x
  306.                         jne .if_e
  307.                         mov eax,dword[y]
  308.                         cmp dword[esi+4],eax ;+4 = .y
  309.                         jne .if_e
  310.                                 ;if(cell[pole_index[i]].x==x && cell[pole_index[i]].y==y){
  311.                                 mov eax,dword[edx] ;fnd=pole_index[i];
  312.                                 jmp .cycle_e ;break;
  313.                         .if_e:
  314.                         jmp .cycle_b
  315.                         .not_found:
  316.                 xor eax,eax ;восстанавливаем нулевое значение если не нашли ячейку (в цикле eax портится при проверке координат)
  317.                 .cycle_e:
  318.                 pop esi edx ecx ebx
  319.         @@:
  320.         .fun_e:
  321.         ret
  322. endp
  323.  
  324. ;output:
  325. ; eax - index
  326. align 4
  327. proc pole_bin_find uses ebx ecx edx edi, mas:dword, fx:dword, fy:dword, k:dword
  328.         xor eax,eax
  329.         mov ebx,1 ;ebx - максимальный порядок для дерева
  330.         @@:
  331.         cmp dword[k],ebx
  332.         jle @f ;while(k>por)
  333.                 shl ebx,1 ;por<<=1;
  334.                 jmp @b
  335.         @@:
  336.         cmp dword[k],ebx
  337.         jge @f ;if(k<por)
  338.                 shr ebx,1 ;por>>=1;
  339.         @@:
  340.         mov ecx,ebx ;i=por;
  341.  
  342.         ;ecx -> i
  343.         ;edi -> mas[i]
  344.         .cycle_b: ;do{
  345.                 shr ebx,1 ;por>>=1;
  346.  
  347.                 mov edi,ecx
  348.                 shl edi,2
  349.                 add edi,dword[mas]
  350.                 ;if(compare_cells_mb(mas[i],fx,fy)){
  351.                 stdcall pole_compare_cells_mb_coords, dword[edi],[fx],[fy]
  352.                 cmp dl,0
  353.                 je .if_u0_e
  354.                         @@: ;while(i+por>k)
  355.                         mov edx,ecx
  356.                         add edx,ebx
  357.                         cmp edx,dword[k] ;i+por>k
  358.                         jle @f
  359.                                 shr ebx,1 ;por>>=1;
  360.                                 jmp @b
  361.                         @@:
  362.                         add ecx,ebx ;i+=por;
  363.                         jmp .if_e
  364.                 .if_u0_e:
  365.                 ;else if(compare_cells_bm(mas[i],fx,fy))i-=por;
  366.                 stdcall pole_compare_cells_bm_coords, dword[edi],[fx],[fy]
  367.                 cmp dl,0
  368.                 je .if_u1_e
  369.                         sub ecx,ebx
  370.                         jmp .if_e
  371.                 .if_u1_e:
  372.                 ;else { m=i; por=0; }
  373.                         mov eax,ecx
  374.                         xor ebx,ebx
  375.                 .if_e:
  376.         cmp ebx,0
  377.         jne .cycle_b ;}while(por);
  378.  
  379.         ret
  380. endp
  381.  
  382. ;сдвиг всех ячеек (и объектов)
  383. align 4
  384. proc pole_move_all, pole:dword, m_d_x:dword, m_d_y:dword
  385. pushad
  386.         mov edi,dword[pole]
  387.         mov edx,[m_d_x]
  388.         mov esi,[m_d_y]
  389.  
  390.         mov eax,pole_index
  391.         cmp dword[eax],0
  392.         je .end_0 ;если нет ячеек (проводов) то выход
  393.  
  394.         mov ecx,dword[eax]
  395.         cld
  396.         @@: ;цикл по всем ячейкам
  397.                 add eax,4
  398.                 mov ebx,[eax]
  399.                 imul ebx,sizeof.Cell
  400.                 add ebx,pole_data
  401.  
  402.                 add dword[ebx+offs_cell_x],edx
  403.                 add dword[ebx+offs_cell_y],esi
  404.                 loop @b
  405.         .end_0:
  406.  
  407.         ;цикл по логическим элементам и подписям
  408.         stdcall dword[tl_node_poi_get_info],0,tree1
  409.         pop eax
  410.         @@:
  411.                 cmp eax,0
  412.                 je .end_1
  413.                 cmp word[eax],el_icon_elems ;получение через eax тип иконки
  414.                 je .mov_1
  415.                 cmp word[eax],el_icon_captions
  416.                 je .mov_1
  417.                         jmp .end_mov_1
  418.                 .mov_1:
  419.                         stdcall [tl_node_poi_get_data], eax, tree1
  420.                         pop ecx
  421.  
  422.                         add [ecx],edx ;coord x
  423.                         add [ecx+4],esi ;coord y
  424.                 .end_mov_1:
  425.                 stdcall dword[tl_node_poi_get_next_info],eax,tree1
  426.                 pop eax ;переходим к следущему узлу
  427.                 jmp @b
  428.         .end_1:
  429.  
  430. popad
  431.         ret
  432. endp
  433.  
  434. ;output:
  435. ; dl
  436. align 4
  437. proc pole_compare_cells_bm_coords uses eax ebx ecx, i0:dword, fx:dword, fy:dword
  438.         get_cell_offset eax,[i0]
  439.         ;eax -> cell[i0]
  440.         mov ebx,dword[fx]
  441.         cmp dword[eax],ebx
  442.         jle @f
  443.                 mov dl,1
  444.                 jmp .fun_e
  445.         @@:
  446.         mov ecx,dword[fy]
  447.         cmp dword[eax+4],ecx
  448.         jle @f
  449.         cmp dword[eax],ebx
  450.         jne @f
  451.                 mov dl,1
  452.                 jmp .fun_e
  453.         @@:
  454.         xor dl,dl
  455.         .fun_e:
  456.         ret
  457. endp
  458.  
  459. ;output:
  460. ; dl
  461. align 4
  462. proc pole_compare_cells_mb_coords uses eax ebx ecx, i0:dword, fx:dword, fy:dword
  463.         get_cell_offset eax,[i0]
  464.         ;eax -> cell[i0]
  465.         mov ebx,dword[fx]
  466.         cmp dword[eax],ebx
  467.         jge @f
  468.                 mov dl,1
  469.                 jmp .fun_e
  470.         @@:
  471.         mov ecx,dword[fy]
  472.         cmp dword[eax+4],ecx
  473.         jge @f
  474.         cmp dword[eax],ebx
  475.         jne @f
  476.                 mov dl,1
  477.                 jmp .fun_e
  478.         @@:
  479.         xor dl,dl
  480.         .fun_e:
  481.         ret
  482. endp
  483.  
  484. ;output:
  485. ; dl
  486. align 4
  487. proc pole_compare_cells_bm, i0:dword, i1:dword
  488.         push eax ebx ecx
  489.         get_cell_offset eax,[i0] ;eax -> cell[i0]
  490.         get_cell_offset ebx,[i1] ;ebx -> cell[i1]
  491.         mov ecx,dword[ebx] ;+0 = .x
  492.         cmp dword[eax],ecx
  493.         jle @f ;x0>x1
  494.                 mov dl,1
  495.                 jmp .fun_e
  496.         @@:
  497.         jne @f ;x0==x1
  498.         mov ecx,dword[ebx+4] ;+4 = .y
  499.         cmp dword[eax+4],ecx
  500.         jle @f ;y0>y1
  501.                 mov dl,1
  502.                 jmp .fun_e
  503.         @@:
  504.         xor dl,dl
  505.         .fun_e:
  506.         pop ecx ebx eax
  507.         ret
  508. endp
  509.  
  510. ;description:
  511. ; чистка ячеек (проводов), установка на всех проводах 0-го сигнала
  512. ; нужно вызывать при формировании или перед запуском схемы
  513. align 4
  514. proc pole_reset_cells uses eax ebx ecx edi, pole:dword
  515.         mov edi,dword[pole]
  516.         mov eax,pole_index
  517.         cmp dword[eax],0
  518.         je .fun_e ;если нет ячеек (проводов) то выход
  519.  
  520.         mov ecx,dword[eax]
  521.         cld
  522.         @@: ;цикл по всем ячейкам
  523.                 add eax,4
  524.                 mov ebx,[eax]
  525.                 imul ebx,sizeof.Cell
  526.                 add ebx,pole_data
  527.                 ;and byte[ebx+offs_cell_liv],0xfe ;сброс младшего бита
  528.                 cmp byte[ebx+offs_cell_liv],2
  529.                 je .no_clear
  530.                         mov byte[ebx+offs_cell_liv],0
  531.                 .no_clear:
  532.                 loop @b
  533.         .fun_e:
  534.         ret
  535. endp
  536.  
  537. align 4
  538. proc p_paint_elems uses eax esi
  539.         stdcall dword[tl_node_poi_get_info],0,tree1
  540.         pop esi
  541.         @@:
  542.                 cmp esi,0
  543.                 je @f
  544.                 cmp word[esi],el_icon_elems ;получение через esi тип иконки
  545.                 jne .end_element
  546.                         stdcall [tl_node_poi_get_data], esi, tree1
  547.                         pop eax
  548.                         stdcall el_draw, eax
  549.                 .end_element:
  550.                 cmp word[esi],el_icon_captions ;получение через esi тип иконки
  551.                 jne .end_caption
  552.                         stdcall [tl_node_poi_get_data], esi, tree1
  553.                         pop eax
  554.                         stdcall capt_draw, eax
  555.                 .end_caption:
  556.                 stdcall dword[tl_node_poi_get_next_info],esi,tree1
  557.                 pop esi ;переходим к следущему узлу
  558.                 jmp @b
  559.         @@:
  560.         ret
  561. endp
  562.  
  563. ;description:
  564. ; функция рисования элемента на поле
  565. align 4
  566. proc el_draw, h_elem:dword
  567.         pushad
  568. ;el_offs_nam
  569.         mov edi,[h_elem]
  570.         mov eax,[edi] ;coord x
  571.         mov ebx,[edi+4] ;coord y
  572.  
  573.         movzx edi,byte[edi+sp_offs_el_type]
  574.         imul edi,size_el_opt
  575.         add edi,el_opt_beg ;edi - указатель на структуру со свойствами элемента
  576.  
  577.         movzx ecx,byte[edi+el_offs_box_x]
  578.         movzx edx,byte[edi+el_offs_box_y]
  579.         dec ecx
  580.         dec edx
  581.  
  582.         push eax ebx
  583.                 mov esi,[h_elem]
  584.                 movzx esi,byte[esi+8]
  585.                 push dword[edi+el_offs_col]
  586.                 push ebx
  587.                 push eax
  588.                 stdcall move_rotate_n90, ecx,edx,esi
  589.                 stdcall draw_scaled_rect, eax,ebx ;рисовани корпуса элемента
  590.         pop ebx eax
  591.  
  592.         ;*** алгоритм рисования ног ***
  593.         movzx esi,byte[zoom]
  594.         cmp esi,1
  595.         jne .end_m1
  596.                 ;*** рисование ног при 1-м масштабе ***
  597.                 ;входные ноги
  598.                 mov esi,[h_elem]
  599.                 stdcall el_get_leg_coords,esi,0 ;установка параметров 0-й ноги
  600.                 add eax,[Cor_x]
  601.                 add ebx,[Cor_y]
  602.                 movzx esi,byte[esi+8]
  603.                 stdcall move_rotate_n90, 1,0,esi
  604.                 mov edx,1
  605.                 @@:
  606.                         stdcall [buf2d_set_pixel], buf_0, eax,ebx,dword[edi+el_offs_col]
  607.                         mov ecx,[edi+el_offs_legs_inp]
  608.                         movzx ecx,byte[ecx+edx]
  609.                         cmp ecx,0
  610.                         je @f
  611.                         stdcall move_rotate_n90, 0,ecx,esi
  612.                         inc edx
  613.                         jmp @b
  614.                 @@:
  615.  
  616.                 ;выходные ноги
  617.                 mov esi,[h_elem]
  618.                 stdcall el_get_leg_coords,esi,(1 shl 16) ;установка параметров 0-й ноги
  619.                 add eax,[Cor_x] ;для работы с buf2d_line
  620.                 add ebx,[Cor_y] ;для работы с buf2d_line
  621.                 movzx esi,byte[esi+8]
  622.                 stdcall move_rotate_n90, -2,0,esi
  623.                 mov edx,el_offs_legs_out
  624.                 inc edx
  625.                 @@:
  626.                         push dword[edi+el_offs_col]
  627.                         stdcall move_rotate_n90, 1,0,esi
  628.                         push ebx
  629.                         push eax
  630.                         stdcall move_rotate_n90, -1,0,esi
  631.                         ;stdcall draw_scaled_rect, eax,ebx
  632.                         stdcall [buf2d_line], buf_0, eax,ebx
  633.                         movzx ecx,byte[edi+edx]
  634.                         cmp ecx,0
  635.                         je @f
  636.                         stdcall move_rotate_n90, 0,ecx,esi
  637.                         inc edx
  638.                         jmp @b
  639.                 @@:
  640.  
  641.                 jmp .end_mn
  642.         .end_m1:
  643.                 ;*** рисование ног при n-м масштабе ***
  644.                 ;входные ноги
  645.                 xor edx,edx
  646.                 @@:
  647.                         stdcall el_get_leg_coords,[h_elem],edx
  648.                         mov ecx,eax
  649.                         or ecx,ebx
  650.                         jz @f
  651.                         mov ecx,[h_elem]
  652.                         movzx ecx,byte[ecx+8]
  653.                         stdcall move_rotate_n90, 1,0,ecx
  654.                         add eax,[Cor_x]
  655.                         add ebx,[Cor_y]
  656.                         imul eax,esi
  657.                         imul ebx,esi
  658.                         stdcall [buf2d_filled_rect_by_size], buf_0, eax,ebx,esi,esi, dword[edi+el_offs_col]
  659.                         inc edx
  660.                         jmp @b
  661.                 @@:
  662.  
  663.                 ;выходные ноги
  664.                 mov edx,(1 shl 16)
  665.                 @@:
  666.                         stdcall el_get_leg_coords,[h_elem],edx
  667.                         mov ecx,eax
  668.                         or ecx,ebx
  669.                         jz @f
  670.                         mov ecx,[h_elem]
  671.                         movzx ecx,byte[ecx+8]
  672.  
  673.                         push dword[edi+el_offs_col]
  674.                         stdcall move_rotate_n90, -2,0,ecx
  675.                         push ebx
  676.                         push eax
  677.                         stdcall move_rotate_n90, 1,0,ecx
  678.                         stdcall draw_scaled_rect, eax,ebx
  679.  
  680.                         inc edx
  681.                         jmp @b
  682.                 @@:            
  683.         .end_mn:
  684.         popad
  685.         ret
  686. endp
  687.  
  688. align 4
  689. proc capt_draw uses eax ebx edi esi, h_capt:dword
  690.         mov edi,[h_capt]
  691.         mov eax,[edi] ;coord x
  692.         mov ebx,[edi+4] ;coord y
  693.         add eax,[Cor_x]
  694.         add ebx,[Cor_y]
  695.  
  696.         movzx esi,byte[zoom]
  697.         cmp esi,1
  698.         jle @f
  699.                 imul eax,esi
  700.                 imul ebx,esi
  701.         @@:
  702.  
  703.         add edi,capt_offs ;edi - указатель на полную подпись (с координатами)
  704.         call str_next_val
  705.         call str_next_val
  706.         ;call str_next_val
  707.         stdcall [buf2d_draw_text], buf_0, buf_font,edi,eax,ebx,color_caption ;рисуем строку с текстом
  708.         ret
  709. endp
  710.  
  711. ;description:
  712. ; подфункция для рисования увеличенных прямоугольников на схеме
  713. align 4
  714. proc draw_scaled_rect uses eax ebx ecx edx edi, x0:dword,y0:dword,x1:dword,y1:dword, color:dword
  715.         movzx edi,byte[zoom]
  716.         mov edx,[y1]
  717.         mov ecx,[x1]
  718.         mov ebx,[y0]
  719.         mov eax,[x0]
  720.  
  721.         cmp eax,ecx
  722.         jle @f
  723.                 xchg eax,ecx
  724.         @@:
  725.         sub ecx,eax
  726.         cmp ebx,edx
  727.         jle @f
  728.                 xchg ebx,edx
  729.         @@:
  730.         sub edx,ebx
  731.  
  732.         inc ecx
  733.         inc edx
  734.  
  735.         imul edx,edi
  736.         imul ecx,edi
  737.         add ebx,[Cor_y]
  738.         imul ebx,edi
  739.         add eax,[Cor_x]
  740.         imul eax,edi
  741.  
  742.         stdcall [buf2d_filled_rect_by_size], buf_0, eax,ebx,ecx,edx, dword[color]
  743.         ret
  744. endp
  745.  
  746. align 4
  747. proc pole_paint, pole:dword
  748.         pushad
  749.  
  750.         ;*** роисование рамки
  751.         mov eax,[Cor_x]
  752.         mov ebx,[Cor_y]
  753.         mov ecx,[shem_w]
  754.         mov edx,[shem_h]
  755.         movzx esi,byte[zoom]
  756.         cmp esi,1
  757.         jle @f
  758.                 imul eax,esi
  759.                 imul ebx,esi
  760.                 imul ecx,esi
  761.                 imul edx,esi
  762.         @@:
  763.         dec eax
  764.         dec ebx
  765.         add ecx,2
  766.         add edx,2
  767.         stdcall [buf2d_rect_by_size], buf_0, eax,ebx, ecx,edx, color_border
  768.  
  769.         ;eax -> firstC
  770.         ;ebx -> i
  771.         ;ecx -> cell[pole_index[i]]
  772.         ;edx -> color
  773.  
  774.         mov edi,dword[pole]
  775.         mov eax,pole_index
  776.         cmp dword[eax],0
  777.         je .no_draw
  778.  
  779.         mov eax,dword[eax]
  780.         mov ebx,1
  781.  
  782. ;---
  783.         @@: ;while(i<pole_b_sort && Cor_x+cell[pole_index[i]].x<0)
  784.                 cmp ebx,pole_b_sort
  785.                 jge @f ;переходим на начало нижнего цикла
  786.                 mov ecx,ebx
  787.                 shl ecx,2
  788.                 add ecx,pole_index
  789.                 get_cell_offset ecx,dword[ecx]
  790.                 mov edx,dword[ecx] ;+0 = .x
  791.                 add edx,dword[Cor_x]
  792.                 cmp edx,0
  793.                 jge @f ;переходим на начало нижнего цикла
  794.                         inc ebx ;i++; // для пропуска ячеек за окном слева
  795.                 jmp @b
  796.         @@:
  797.  
  798.         ;eax -> pole_index[firstC]
  799.         ;ebx -> pole_index[i]
  800.         ;edi -> coord_x
  801.         ;esi -> coord_y
  802.         shl eax,2
  803.         shl ebx,2
  804.         add eax,pole_index
  805.         add ebx,pole_index
  806.  
  807.         cmp byte[zoom],2
  808.         jge .zoom2
  809.         @@: ;for(;i<=fristC;i++){
  810.                 get_cell_offset ecx,dword[ebx]
  811. ;...
  812.                 mov edi,dword[Cor_x]
  813.                 add edi,dword[ecx] ;+0 = .x
  814.                 mov esi,dword[Cor_y]
  815.                 add esi,dword[ecx+4] ;+4 = .y
  816.                 movzx edx,byte[ecx+offs_cell_liv]
  817.                 and edx,3 ;ограничение
  818.                 shl edx,2
  819.                 add edx,shem_colors
  820.                 stdcall [buf2d_set_pixel], buf_0, edi, esi, [edx]
  821. ;...
  822.                 add ebx,4
  823.                 cmp ebx,eax
  824.                 jle @b
  825.  
  826.         jmp .no_draw
  827.         .zoom2:
  828.  
  829.         @@: ;for(;i<=fristC;i++){
  830.                 get_cell_offset ecx,dword[ebx]
  831.  
  832.                 movzx edx,byte[zoom] ;edx используется для внесения zoom в 4 байтное число
  833.                 mov edi,dword[ecx] ;+0 = .x
  834.                 add edi,dword[Cor_x]
  835.                 imul edi,edx
  836.                 mov esi,dword[ecx+4] ;+4 = .y
  837.                 add esi,dword[Cor_y]
  838.                 imul esi,edx
  839.  
  840.                 movzx edx,byte[ecx+offs_cell_liv]
  841.                 and edx,3 ;ограничение
  842.                 shl edx,2
  843.                 add edx,shem_colors
  844.  
  845.                 movzx ecx,byte[zoom]
  846.                 ;;;dec ecx
  847.                 stdcall [buf2d_filled_rect_by_size], buf_0, edi, esi, ecx, ecx, [edx]
  848.                 add ebx,4
  849.                 cmp ebx,eax
  850.                 jle @b
  851.  
  852.         .no_draw:
  853.         popad
  854.         call p_paint_elems
  855.         ret
  856. endp
  857.  
  858. ;Сортировка ячеек поля, нужна для более быстрого поиска
  859. align 4
  860. proc pole_sort uses eax edi, pole:dword
  861.         mov edi,dword[pole]
  862.         mov eax,pole_index
  863.         mov eax,dword[eax] ;firstC -> eax
  864.         stdcall pole_fl_sort, pole_index,eax ;сортируем все ячейки
  865.         mov pole_b_sort,eax ;ставим число отсортированных ячеек равное числу всех существующих ячеек
  866.         ret
  867. endp
  868.  
  869. ;Сортировка вектора a[1..n] методом Флойда
  870. ;Элемент a[0] в сортировке не участвует
  871. align 4
  872. proc pole_fl_sort uses eax ecx edx edi esi, a:dword, n:dword
  873.         mov ecx,dword[a]
  874.         ;Формировать исходное частично упорядоченное дерево
  875.         mov eax,dword[n]
  876.         shr eax,1
  877.         @@: ;for(i=n>>1; i>=2; i--)
  878.                 stdcall pole_fl_surface, ecx,eax,[n] ;(a,i,n)
  879.                 dec eax
  880.                 cmp eax,2
  881.                 jge @b
  882.         ;Выполнить процедуру всплытия Флойда для каждого поддерева
  883.         mov eax,dword[n]
  884.         @@: ;for(i=n; i>=2; i--){
  885.                 stdcall pole_fl_surface, ecx,1,eax ;(a,1,i)
  886.                 ;Поместить найденный максимальный элемент в конец списка
  887.                 mov edi,eax
  888.                 shl edi,2
  889.                 add edi,ecx ;edi -> &a[i]
  890.                 mov esi,dword[edi] ;w=a[i];
  891.                 mov edx,dword[ecx+4]
  892.                 mov dword[edi],edx ;a[i]=a[1];
  893.                 mov dword[ecx+4],esi ;a[1]=w;
  894.  
  895.                 dec eax
  896.                 cmp eax,2
  897.                 jge @b
  898.         ret
  899. endp
  900.  
  901. ;Процедура всплытия Флойда по дереву a[1..k]
  902. align 4
  903. proc pole_fl_surface, a:dword, i:dword, k:dword
  904. locals
  905.         copy dd ?
  906. endl
  907.         pushad
  908.         ;edx -> ...
  909.         ;edi -> m
  910.         ;esi -> j
  911.         mov eax,dword[a]
  912.         mov ebx,dword[i]
  913.         mov ecx,dword[k]
  914.  
  915.         mov edx,ebx
  916.         shl edx,2
  917.         add edx,eax
  918.         mov edx,dword[edx]
  919.         mov dword[copy],edx ;copy=a[i];
  920.         mov edi,ebx
  921.         shl edi,1 ;m=i<<1;
  922.         .cycle_b: ;while (m<=k) {
  923.                 cmp edi,ecx
  924.                 jg .cycle_e
  925.                 jne @f ;if (m==k) j=m;
  926.                         mov esi,edi
  927.                         jmp .else_e
  928.                 @@: ;else if (pole_compare_cells_bm(a[m],a[m+1])) j=m;
  929.                 mov edx,edi
  930.                 shl edx,2
  931.                 add edx,eax
  932.                 stdcall pole_compare_cells_bm, dword[edx],dword[edx+4]
  933.                 cmp dl,0
  934.                 je @f
  935.                         mov esi,edi
  936.                         jmp .else_e
  937.                 @@: ;else j=m+1;
  938.                         mov esi,edi
  939.                         inc esi
  940.                 .else_e:
  941.  
  942.                 ;if (pole_compare_cells_bm(a[j],copy)) {
  943.                 mov edx,esi
  944.                 shl edx,2
  945.                 add edx,eax
  946.                 stdcall pole_compare_cells_bm, dword[edx],dword[copy]
  947.                 cmp dl,0
  948.                 je .cycle_e ;} else break; //выход из цикла
  949.  
  950.                 mov edx,esi
  951.                 shl edx,2
  952.                 add edx,eax
  953.                 push dword[edx] ;push a[j];
  954.                 mov edx,ebx
  955.                 shl edx,2
  956.                 add edx,eax
  957.                 pop dword[edx] ;a[i]=a[j];
  958.                 mov ebx,esi ;i=j;
  959.                 mov edi,ebx
  960.                 shl edi,1 ;m=i<<1;
  961.  
  962.                 jmp .cycle_b
  963.         .cycle_e:
  964.  
  965.         ;значения многих регистров уже не важны т. к. конец функции
  966.         shl ebx,2
  967.         add eax,ebx
  968.         mov edx,dword[copy]
  969.         mov dword[eax],edx ;a[i]=copy;
  970.  
  971.         popad
  972.         ret
  973. endp
  974. ;--------------------------------------
  975.  
  976. align 4
  977. proc pole_draw_pok uses eax ebx ecx edx edi esi, pole:dword
  978.         ;mov edi,dword[pole]
  979.  
  980.         mov eax,4 ;рисование текста
  981.         mov ebx,400*65536+5
  982.         mov ecx,[sc.work_text]
  983.         or  ecx,0x80000000 ;or (1 shl 30)
  984.         mov edx,txt_zoom
  985.         ;mov edi,[sc.work]
  986.         int 0x40
  987.  
  988.         add bx,9
  989.         mov edx,txt_osob
  990.         int 0x40
  991.  
  992.         add bx,9
  993.         mov edx,txt_info
  994.         int 0x40
  995.  
  996.         mov eax,47
  997.         movzx ecx,byte[zoom]
  998.         mov ebx,(2 shl 16)
  999.         mov edx,(400+6*9)*65536+5
  1000.         mov esi,[sc.work_button_text]
  1001.         or  esi,(1 shl 30)
  1002.         mov edi,[sc.work_button]
  1003.         int 0x40 ;масштаб
  1004.  
  1005.         mov edi,dword[pole]
  1006.         mov ecx,pole_index
  1007.         mov ecx,[ecx]
  1008.         mov edi,[sc.work_button]
  1009.         mov ebx,(5 shl 16)
  1010.         add edx,(6*0)*65536+9
  1011.         int 0x40 ;число точек
  1012.         ret
  1013. endp
  1014.  
  1015. align 4
  1016. but_zoom_p:
  1017.         cmp byte[zoom],16
  1018.         jge @f
  1019.                 pushad
  1020.                 ;вычисление сдвигов для поля, которые обеспечат центровку поля при увеличении масштаба
  1021.                 movzx ecx,byte[zoom]
  1022.                 xor edx,edx
  1023.                 mov eax,dword[buf_0.w]
  1024.                 shr eax,1 ;в eax половина ширины поля
  1025.                 mov ebx,eax ;делаем резервную копию eax
  1026.                 div ecx ;делим eax на текущий масштаб
  1027.                 xchg eax,ebx
  1028.                 xor edx,edx
  1029.                 inc ecx
  1030.                 div ecx ;делим eax на новый масштаб
  1031.                 sub ebx,eax ;вычисляется сдвиг поля который обеспечит центровку поля
  1032.                 sub dword[Cor_x],ebx ;сдвигаем поле зрения по оси x
  1033.                 xor ecx,ecx
  1034.                 mov cl,byte[zoom]
  1035.                 xor edx,edx
  1036.                 mov eax,dword[buf_0.h]
  1037.                 shr eax,1
  1038.                 mov ebx,eax
  1039.                 div ecx
  1040.                 xchg eax,ebx
  1041.                 xor edx,edx
  1042.                 inc ecx
  1043.                 div ecx
  1044.                 sub ebx,eax
  1045.                 sub dword[Cor_y],ebx ;сдвигаем поле зрения по оси y
  1046.  
  1047.                 inc byte[zoom]
  1048.                 stdcall pole_draw_pok, pole
  1049.                 popad
  1050.  
  1051.                 .buf_clear:
  1052.                         call redraw_pole
  1053.         @@:
  1054.         ret
  1055.  
  1056. align 4
  1057. but_zoom_m:
  1058.         cmp byte[zoom],1
  1059.         jle @f
  1060.                 pushad
  1061.                 ;вычисление сдвигов для поля, которые обеспечат центровку поля при уменьшении масштаба
  1062.                 movzx ecx,byte[zoom]
  1063.                 xor edx,edx
  1064.                 mov eax,dword[buf_0.w]
  1065.                 shr eax,1 ;в eax половина ширины поля
  1066.                 mov ebx,eax ;делаем резервную копию eax
  1067.                 div ecx ;делим eax на текущий масштаб
  1068.                 xchg eax,ebx
  1069.                 xor edx,edx
  1070.                 dec ecx
  1071.                 div ecx ;делим eax на новый масштаб
  1072.                 sub ebx,eax ;вычисляется сдвиг поля который обеспечит центровку поля
  1073.                 sub dword[Cor_x],ebx ;сдвигаем поле зрения по оси x
  1074.                 xor ecx,ecx
  1075.                 mov cl,byte[zoom]
  1076.                 xor edx,edx
  1077.                 mov eax,dword[buf_0.h]
  1078.                 shr eax,1
  1079.                 mov ebx,eax
  1080.                 div ecx
  1081.                 xchg eax,ebx
  1082.                 xor edx,edx
  1083.                 dec ecx
  1084.                 div ecx
  1085.                 sub ebx,eax
  1086.                 sub dword[Cor_y],ebx ;сдвигаем поле зрения по оси y
  1087.  
  1088.                 dec byte[zoom]
  1089.                 stdcall pole_draw_pok, pole
  1090.                 popad
  1091.  
  1092.                 .buf_clear:
  1093.                         call redraw_pole
  1094.         @@:
  1095.         ret
  1096.  
  1097. ;центровка схемы по центру экрана
  1098. align 4
  1099. proc but_center uses eax ebx ecx edx
  1100.         movzx ecx,byte[zoom]
  1101.         cmp ecx,1
  1102.         jle .end_m_1
  1103.                 mov eax,[buf_0.w]
  1104.                 mov ebx,[shem_w]
  1105.                 imul ebx,ecx
  1106.  
  1107.                 sub eax,ebx
  1108.                 xor edx,edx
  1109.                 shl ecx,1
  1110.                 cmp eax,0
  1111.                 jge @f
  1112.                         neg eax
  1113.                         inc eax
  1114.                         div ecx
  1115.                         neg eax
  1116.                         inc eax
  1117.                         jmp .set_x
  1118.                 @@:
  1119.                         div ecx
  1120.                 .set_x:
  1121.                 mov [Cor_x],eax
  1122.                 mov eax,[buf_0.h]
  1123.                 mov ebx,[shem_h]
  1124.                 shr ecx,1
  1125.                 imul ebx,ecx
  1126.                 sub eax,ebx
  1127.                 xor edx,edx
  1128.                 shl ecx,1
  1129.                 cmp eax,0
  1130.                 jge @f
  1131.                         neg eax
  1132.                         inc eax
  1133.                         div ecx
  1134.                         neg eax
  1135.                         inc eax
  1136.                         jmp .set_y
  1137.                 @@:
  1138.                         div ecx
  1139.                 .set_y:
  1140.                 mov [Cor_y],eax
  1141.                 jmp .end_m_n
  1142.         .end_m_1:
  1143.                 mov eax,[buf_0.w]
  1144.                 sub eax,[shem_w]
  1145.                 shr eax,1
  1146.                 bt eax,30
  1147.                 jnc @f
  1148.                         bts eax,31
  1149.                 @@:
  1150.                 mov [Cor_x],eax
  1151.                 mov eax,[buf_0.h]
  1152.                 sub eax,[shem_h]
  1153.                 shr eax,1
  1154.                 bt eax,30
  1155.                 jnc @f
  1156.                         bts eax,31
  1157.                 @@:
  1158.                 mov [Cor_y],eax
  1159.         .end_m_n:
  1160.         call redraw_pole
  1161.         ret
  1162. endp
  1163.  
  1164. align 4
  1165. but_pole_up:
  1166.         push eax ecx edx
  1167.         mov eax,dword[buf_0.h]
  1168.         shr eax,2
  1169.         movzx ecx,byte[zoom]
  1170.         cmp cx,2
  1171.         jl @f ;деление на величину zoom
  1172.                 xor edx,edx
  1173.                 div ecx
  1174.         @@:
  1175.         add dword[Cor_y],eax
  1176.         pop edx ecx eax
  1177.         call redraw_pole
  1178.         ret
  1179.  
  1180. align 4
  1181. but_pole_dn:
  1182.         push eax ecx edx
  1183.         mov eax,dword[buf_0.h]
  1184.         shr eax,2
  1185.         xor ecx,ecx
  1186.         mov cl,byte[zoom]
  1187.         cmp cx,2
  1188.         jl @f ;деление на величину zoom
  1189.                 xor edx,edx
  1190.                 div ecx
  1191.         @@:
  1192.         sub dword[Cor_y],eax
  1193.         pop edx ecx eax
  1194.         call redraw_pole
  1195.         ret
  1196.  
  1197. align 4
  1198. but_pole_left:
  1199.         push eax ecx edx
  1200.         mov eax,dword[buf_0.w]
  1201.         shr eax,2
  1202.         xor ecx,ecx
  1203.         mov cl,byte[zoom]
  1204.         cmp cx,2
  1205.         jl @f ;деление на величину zoom
  1206.                 xor edx,edx
  1207.                 div ecx
  1208.         @@:
  1209.         add dword[Cor_x],eax
  1210.         pop edx ecx eax
  1211.         call redraw_pole
  1212.         ret
  1213.  
  1214. align 4
  1215. but_pole_right:
  1216.         push eax ecx edx
  1217.         mov eax,dword[buf_0.w]
  1218.         shr eax,2
  1219.         xor ecx,ecx
  1220.         mov cl,byte[zoom]
  1221.         cmp cx,2
  1222.         jl @f ;деление на величину zoom
  1223.                 xor edx,edx
  1224.                 div ecx
  1225.         @@:
  1226.         sub dword[Cor_x],eax
  1227.         pop edx ecx eax
  1228.         call redraw_pole
  1229.         ret
  1230.  
  1231. ;output:
  1232. ; edx - count created points
  1233. align 4
  1234. proc shem_create_line uses eax ebx ecx edi, x:dword, y:dword, opt:dword
  1235.         mov edi,pole
  1236.         xor edx,edx
  1237.  
  1238.         mov ebx,[x]
  1239.         mov ecx,[y]
  1240.         bt dword[opt],0
  1241.         jnc @f
  1242.         .line_lr:
  1243.                 inc ebx
  1244.                 cmp ebx,[shem_w]
  1245.                 jge @f
  1246.                 stdcall pole_cell_find, pole,ebx,ecx
  1247.                 cmp eax,0
  1248.                 je .u0
  1249.                         imul eax,sizeof.Cell
  1250.                         add eax,pole_data
  1251.                         cmp byte[eax+offs_cell_liv],1
  1252.                         jne @f
  1253.                 .u0:
  1254.                 stdcall pole_cell_creat, pole,ebx,ecx,1
  1255.                 inc edx
  1256.                 jmp .line_lr
  1257.         @@:
  1258.  
  1259.         mov ebx,[x]
  1260.         ;mov ecx,[y]
  1261.         bt dword[opt],2
  1262.         jnc @f
  1263.         .line_rl:
  1264.                 dec ebx
  1265.                 cmp ebx,0
  1266.                 jl @f
  1267.                 stdcall pole_cell_find, pole,ebx,ecx
  1268.                 cmp eax,0
  1269.                 je .u1
  1270.                         imul eax,sizeof.Cell
  1271.                         add eax,pole_data
  1272.                         cmp byte[eax+offs_cell_liv],1
  1273.                         jne @f
  1274.                 .u1:
  1275.                 stdcall pole_cell_creat, pole,ebx,ecx,1
  1276.                 inc edx
  1277.                 jmp .line_rl
  1278.         @@:
  1279.  
  1280.         mov ebx,[x]
  1281.         mov ecx,[y]
  1282.         bt dword[opt],3
  1283.         jnc @f
  1284.         .line_du:
  1285.                 dec ecx
  1286.                 cmp ecx,0
  1287.                 jl @f
  1288.                 stdcall pole_cell_find, pole,ebx,ecx
  1289.                 cmp eax,0
  1290.                 je .u2
  1291.                         imul eax,sizeof.Cell
  1292.                         add eax,pole_data
  1293.                         cmp byte[eax+offs_cell_liv],1
  1294.                         jne @f
  1295.                 .u2:
  1296.                 stdcall pole_cell_creat, pole,ebx,ecx,1
  1297.                 inc edx
  1298.                 jmp .line_du
  1299.         @@:
  1300.  
  1301.         ;mov ebx,[x]
  1302.         mov ecx,[y]
  1303.         bt dword[opt],1
  1304.         jnc @f
  1305.         .line_ud:
  1306.                 inc ecx
  1307.                 cmp ecx,[shem_h]
  1308.                 jge @f
  1309.                 stdcall pole_cell_find, pole,ebx,ecx
  1310.                 cmp eax,0
  1311.                 je .u3
  1312.                         imul eax,sizeof.Cell
  1313.                         add eax,pole_data
  1314.                         cmp byte[eax+offs_cell_liv],1
  1315.                         jne @f
  1316.                 .u3:
  1317.                 stdcall pole_cell_creat, pole,ebx,ecx,1
  1318.                 inc edx
  1319.                 jmp .line_ud
  1320.         @@:
  1321.  
  1322.         ret
  1323. endp
  1324.  
  1325. align 4
  1326. redraw_pole:
  1327.         stdcall [buf2d_clear], buf_0, [buf_0.color]
  1328.         stdcall pole_paint, pole
  1329.         stdcall [buf2d_draw], buf_0
  1330.         ret
  1331.