Subversion Repositories Kolibri OS

Rev

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