Subversion Repositories Kolibri OS

Rev

Rev 2574 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2462 IgorA 1
;
; функци для создания сигналов
;

;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
2