; ; функци для создания сигналов ; ;color_s0 - сигнал 0 ;color_s1 - сигнал 1 ;color_s2 - точка без пересечения ;color_s3 - временное значение для сохранения size_sign equ 10 sign_x equ 0 sign_y equ 4 sign_a equ 8 sign_z equ 9 sign_data dd 0 ;указатель на массив со структурами сигналов sign_count dd 0 ;текущ. кол. сигналов sign_max dd 0 ;макс. кол. сигналов align 4 proc sign_init uses eax ecx, m_count:dword mov ecx,[m_count] mov [sign_max],ecx imul ecx,size_sign stdcall mem.Alloc, ecx mov [sign_data],eax call sign_clear ret endp ;очистка всех сигналов align 4 proc sign_clear uses eax ecx edi xor eax,eax mov dword[time],eax mov dword[sign_count],eax mov ecx,[sign_max] imul ecx,size_sign mov edi,[sign_data] cld rep stosb ret endp ;очистка одного сигнала align 4 proc sign_clear_one uses ecx edi esi, p_sign:dword mov ecx,size_sign mov esi,[sign_count] dec esi imul esi,ecx add esi,[sign_data] mov edi,[p_sign] cld rep movsb dec dword[sign_count] ret endp ;освобождение памяти занятой массивами для сигналов align 4 proc sign_delete stdcall mem.Free, dword[sign_data] ret endp ;функция для перемещения сигналов align 4 proc sign_move pushad mov ecx,[sign_count] cmp ecx,1 jl .end_f mov esi,ecx dec esi imul esi,size_sign add esi,[sign_data] ;cld .cycle_beg: mov eax,[esi+sign_x] mov ebx,[esi+sign_y] movzx edi,byte[esi+sign_a] movzx edx,byte[esi+sign_z] cmp edx,0 je @f or edi,0x100 @@: ;пытаемся создать разветвление сигнала stdcall move_rotate_n90, 0,-1,edi inc edi stdcall sign_creat,eax,ebx,edi stdcall move_rotate_n90, -2,0,edi add edi,2 stdcall sign_creat,eax,ebx,edi mov eax,[esi+sign_x] mov ebx,[esi+sign_y] inc edi mov eax,[esi+sign_x] mov ebx,[esi+sign_y] shl edx,2 add edx,shem_colors stdcall draw_signal_rect, eax,ebx, dword[edx] ;рисуем сигнал на поле .move_1: stdcall move_rotate_x_n90, 1,edi mov edi,eax stdcall pole_cell_find, pole, edi,ebx cmp eax,0 jne @f stdcall sign_clear_one,esi ;удаление сигнала, если он зашел в тупик jmp .cycle_next @@: imul eax,sizeof.Cell add eax,dword[cell] movzx edx,byte[esi+sign_z] cmp byte[eax+offs_cell_liv],2 jne @f ;если стоит пересечение проводов mov eax,edi movzx edi,byte[esi+sign_a] jmp .move_1 @@: cmp byte[eax+offs_cell_liv],dl jne @f stdcall sign_clear_one,esi ;удаление сигнала, если он попал на область закрашеную данным цветом jmp .cycle_next @@: mov byte[eax+offs_cell_liv],dl ;ставим на поле знак сигнала mov [esi+sign_x],edi mov [esi+sign_y],ebx .cycle_next: sub esi,size_sign ;loop .cycle_beg dec ecx jnz .cycle_beg ;stdcall [buf2d_draw], buf_0 .end_f: popad ret endp align 4 proc sign_creat uses eax ebx ecx edx edi esi, coord_x:dword, coord_y:dword, opt:dword mov edi,[sign_count] cmp edi,[sign_max] jge .end_f mov esi,[coord_x] mov ebx,[coord_y] .found: stdcall pole_cell_find, pole, esi,ebx cmp eax,0 je .end_f mov ecx,[opt] get_cell_offset edx,eax cmp byte[edx+offs_cell_liv],2 jne @f mov eax,esi stdcall move_rotate_x_n90,1,ecx mov esi,eax jmp .found @@: cmp ch,byte[edx+offs_cell_liv] ;проверяем на поле знак сигнала je .end_f ;доделать установку метки в провод, что-бы избежать дублирования сигналов на широких проводах imul edi,size_sign add edi,[sign_data] mov [edi+sign_x],esi mov [edi+sign_y],ebx mov [edi+sign_a],cl mov [edi+sign_z],ch inc dword[sign_count] mov [edx+offs_cell_liv],ch ;ставим на поле знак сигнала ;stdcall draw_signal_rect, [coord_x],[coord_y], 0x800080 .end_f: ret endp ;description: ; подфункция для рисования сигналов на схеме align 4 proc draw_signal_rect uses eax ebx edi, x0:dword,y0:dword, color:dword movzx edi,byte[zoom] mov ebx,[y0] mov eax,[x0] add ebx,[Cor_y] imul ebx,edi add eax,[Cor_x] imul eax,edi stdcall [buf2d_filled_rect_by_size], buf_0, eax,ebx,edi,edi, dword[color] ret endp align 4 proc sign_from_elems locals s_inp dd ? n_leg dd ? endl pushad mov edi,pole ;*** создание сигналов из логических элементов *** stdcall dword[tl_node_poi_get_info],0,tree1 pop esi @@: cmp esi,0 je @f cmp word[esi],el_icon_elems ;получение через esi тип иконки jne .end_add_p3 stdcall [tl_node_poi_get_data], esi, tree1 pop ecx ;*** проверка сигналов на входных ногах mov dword[s_inp],0 mov dword[n_leg],0 ;word[n_leg] - номер входной ноги mov edx,1 .add_p1: stdcall el_get_leg_coords, ecx,dword[n_leg] test eax,eax jnz .get1 test ebx,ebx jnz .get1 jmp .end_add_p1 ;если координаты не взялись (eax=0 && ebx=0), выход из цикла .get1: stdcall pole_cell_find, pole, eax,ebx cmp eax,0 je .get2 imul eax,sizeof.Cell add eax,pole_data cmp byte[eax+offs_cell_liv],1 jne .get2 or dword[s_inp],edx .get2: inc dword[n_leg] shl edx,1 jmp .add_p1 .end_add_p1: ;*** определяем выходную комбинацию битов на основе заданной таблицы работы элемента movzx eax,byte[ecx+sp_offs_el_type] imul eax,size_el_opt add eax,el_opt_beg+el_offs_table mov ebx,[eax] add ebx,dword[s_inp] mov ebx,[ebx] mov dword[s_inp],ebx ;*** установка сигналов на выходных ногах mov dword[n_leg],(1 shl 16) ;word[n_leg] - номер выходной ноги .add_p2: stdcall el_get_leg_coords, ecx,dword[n_leg] test eax,eax jnz .get3 test ebx,ebx jnz .get3 jmp .end_add_p2 ;если координаты не взялись (eax=0 && ebx=0), выход из цикла .get3: movzx edx,byte[ecx+8] ;dl - направление сигнала bt dword[s_inp],0 jnc .set1 or edx,0x100 ;dh - значение сигнала 0 или 1 .set1: stdcall sign_creat,eax,ebx,edx inc dword[n_leg] shr dword[s_inp],1 jmp .add_p2 .end_add_p2: .end_add_p3: stdcall dword[tl_node_poi_get_next_info],esi,tree1 pop esi ;переходим к следущему узлу jmp @b @@: popad ret endp ;создание сигналов на основе подписей align 4 proc sign_from_captions pushad ;mov edi,pole ;*** создание сигналов из подписей *** stdcall dword[tl_node_poi_get_info],0,tree1 pop esi @@: cmp esi,0 je @f cmp word[esi],el_icon_captions ;получение через esi тип иконки jne .end_add_p3 stdcall [tl_node_poi_get_data], esi, tree1 pop ecx cmp byte[ecx+8],'n' je .end_add_p3 ;если надпись информационная, то не создаем сигнала ;xor edx,edx movzx edx,byte[ecx+9] ;первоначальное напрвление выходного сигнала ;*** определяем выходой бит, ;который был установлен в but_set_0 и but_set_1 cmp byte[ecx+8],'o' jne .end_add_p1 or edx,0x100 .end_add_p1: stdcall sign_creat,dword[ecx],dword[ecx+4],edx .end_add_p3: stdcall dword[tl_node_poi_get_next_info],esi,tree1 pop esi ;переходим к следущему узлу jmp @b @@: popad ret endp ; изменяем первоначальное напрвление выходного сигнала ; выставляются 2 направления: слева на право, справа на лево ; остальные 2 возможных направления не учитываются, ; т. к. повороты сигналов возможны и без них align 4 proc sign_set_captions_angles pushad mov edi,pole stdcall dword[tl_node_poi_get_info],0,tree1 pop esi .cycle0: cmp esi,0 je .cycle0_end cmp word[esi],el_icon_captions ;получение через esi тип иконки jne .end_p0 stdcall [tl_node_poi_get_data], esi, tree1 pop ecx mov ebx,[ecx] ;ebx = coord x xor edx,edx dec ebx stdcall pole_cell_find, edi, ebx,dword[ecx+4] cmp eax,0 je @f mov edx,2 ;jmp .set_angle @@: ;.set_angle: mov byte[ecx+9],dl ;первоначальное напрвление выходного сигнала .end_p0: stdcall dword[tl_node_poi_get_next_info],esi,tree1 pop esi ;переходим к следущему узлу jmp .cycle0 .cycle0_end: popad ret endp