Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2462 IgorA 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] ;граница для сортированных ячеек
2501 IgorA 30
offs_pole_b_sort equ 12
2462 IgorA 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
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]
2501 IgorA 155
	mov ebx,edi
156
	add ebx,offs_pole_b_sort
2462 IgorA 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
 
2501 IgorA 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
 
2462 IgorA 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
 
2501 IgorA 206
if debug
2462 IgorA 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]
2501 IgorA 218
 
219
	mov eax,pole_b_sort
2462 IgorA 220
	mov edi,open_file_lif
2501 IgorA 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
2462 IgorA 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++)
2501 IgorA 299
			inc ebx
300
			cmp ebx,ecx
301
			jg .not_found
2462 IgorA 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:
2501 IgorA 314
			jmp .cycle_b
315
			.not_found:
2462 IgorA 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
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
 
2501 IgorA 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
 
2462 IgorA 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
2487 IgorA 604
		mov edx,1
2462 IgorA 605
		@@:
606
			stdcall [buf2d_set_pixel], buf_0, eax,ebx,dword[edi+el_offs_col]
2487 IgorA 607
			mov ecx,[edi+el_offs_legs_inp]
608
			movzx ecx,byte[ecx+edx]
2462 IgorA 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
 
2507 IgorA 688
;description:
689
;рисование подписей
2462 IgorA 690
align 4
691
proc capt_draw uses eax ebx edi esi, h_capt:dword
692
	mov edi,[h_capt]
693
	mov eax,[edi] ;coord x
694
	mov ebx,[edi+4] ;coord y
2507 IgorA 695
 
696
	movzx esi,byte[zoom]
697
	cmp esi,3
698
	jl @f
699
		;рисование рамки, вокруг занятой точки
700
		stdcall draw_point_border, eax,ebx, color_caption
701
	@@:
702
 
2462 IgorA 703
	add eax,[Cor_x]
704
	add ebx,[Cor_y]
705
 
706
	cmp esi,1
707
	jle @f
708
		imul eax,esi
709
		imul ebx,esi
710
	@@:
711
 
2507 IgorA 712
	cmp esi,3
713
	jl @f
714
		;сдвиг надписи с учетом рамки
715
		add eax,esi
716
		inc eax
717
	@@:
718
 
2462 IgorA 719
	add edi,capt_offs ;edi - указатель на полную подпись (с координатами)
720
	call str_next_val
721
	call str_next_val
722
	stdcall [buf2d_draw_text], buf_0, buf_font,edi,eax,ebx,color_caption ;рисуем строку с текстом
723
	ret
724
endp
725
 
726
;description:
2507 IgorA 727
; функция для выделения точечных объектов на крупных масштабах
728
; данная функция очень похожа на draw_signal_rect
729
align 4
730
proc draw_point_border uses eax ebx edi, x0:dword,y0:dword, color:dword
731
	movzx edi,byte[zoom]
732
	mov ebx,[y0]
733
	mov eax,[x0]
734
 
735
	add ebx,[Cor_y]
736
	imul ebx,edi
737
	add eax,[Cor_x]
738
	imul eax,edi
739
 
740
	stdcall [buf2d_rect_by_size], buf_0, eax,ebx,edi,edi, dword[color]
741
	ret
742
endp
743
 
744
;description:
2462 IgorA 745
; подфункция для рисования увеличенных прямоугольников на схеме
746
align 4
747
proc draw_scaled_rect uses eax ebx ecx edx edi, x0:dword,y0:dword,x1:dword,y1:dword, color:dword
748
	movzx edi,byte[zoom]
749
	mov edx,[y1]
750
	mov ecx,[x1]
751
	mov ebx,[y0]
752
	mov eax,[x0]
753
 
754
	cmp eax,ecx
755
	jle @f
756
		xchg eax,ecx
757
	@@:
758
	sub ecx,eax
759
	cmp ebx,edx
760
	jle @f
761
		xchg ebx,edx
762
	@@:
763
	sub edx,ebx
764
 
765
	inc ecx
766
	inc edx
767
 
768
	imul edx,edi
769
	imul ecx,edi
770
	add ebx,[Cor_y]
771
	imul ebx,edi
772
	add eax,[Cor_x]
773
	imul eax,edi
774
 
775
	stdcall [buf2d_filled_rect_by_size], buf_0, eax,ebx,ecx,edx, dword[color]
776
	ret
777
endp
778
 
779
align 4
780
proc pole_paint, pole:dword
781
	pushad
782
 
783
	;*** роисование рамки
784
	mov eax,[Cor_x]
785
	mov ebx,[Cor_y]
786
	mov ecx,[shem_w]
787
	mov edx,[shem_h]
788
	movzx esi,byte[zoom]
789
	cmp esi,1
790
	jle @f
791
		imul eax,esi
792
		imul ebx,esi
793
		imul ecx,esi
794
		imul edx,esi
795
	@@:
796
	dec eax
797
	dec ebx
798
	add ecx,2
799
	add edx,2
800
	stdcall [buf2d_rect_by_size], buf_0, eax,ebx, ecx,edx, color_border
801
 
802
	;eax -> firstC
803
	;ebx -> i
804
	;ecx -> cell[pole_index[i]]
805
	;edx -> color
806
 
807
	mov edi,dword[pole]
808
	mov eax,pole_index
809
	cmp dword[eax],0
810
	je .no_draw
811
 
812
	mov eax,dword[eax]
813
	mov ebx,1
814
 
815
;---
816
	@@: ;while(i
817
		cmp ebx,pole_b_sort
818
		jge @f ;переходим на начало нижнего цикла
819
		mov ecx,ebx
820
		shl ecx,2
821
		add ecx,pole_index
822
		get_cell_offset ecx,dword[ecx]
823
		mov edx,dword[ecx] ;+0 = .x
824
		add edx,dword[Cor_x]
825
		cmp edx,0
826
		jge @f ;переходим на начало нижнего цикла
827
			inc ebx ;i++; // для пропуска ячеек за окном слева
828
		jmp @b
829
	@@:
830
 
831
	;eax -> pole_index[firstC]
832
	;ebx -> pole_index[i]
833
	;edi -> coord_x
834
	;esi -> coord_y
835
	shl eax,2
836
	shl ebx,2
837
	add eax,pole_index
838
	add ebx,pole_index
839
 
840
	cmp byte[zoom],2
841
	jge .zoom2
842
	@@: ;for(;i<=fristC;i++){
843
		get_cell_offset ecx,dword[ebx]
844
;...
845
		mov edi,dword[Cor_x]
846
		add edi,dword[ecx] ;+0 = .x
847
		mov esi,dword[Cor_y]
848
		add esi,dword[ecx+4] ;+4 = .y
849
		movzx edx,byte[ecx+offs_cell_liv]
850
		and edx,3 ;ограничение
851
		shl edx,2
852
		add edx,shem_colors
853
		stdcall [buf2d_set_pixel], buf_0, edi, esi, [edx]
854
;...
855
		add ebx,4
856
		cmp ebx,eax
857
		jle @b
858
 
859
	jmp .no_draw
860
	.zoom2:
861
 
862
	@@: ;for(;i<=fristC;i++){
863
		get_cell_offset ecx,dword[ebx]
864
 
865
		movzx edx,byte[zoom] ;edx используется для внесения zoom в 4 байтное число
866
		mov edi,dword[ecx] ;+0 = .x
867
		add edi,dword[Cor_x]
868
		imul edi,edx
869
		mov esi,dword[ecx+4] ;+4 = .y
870
		add esi,dword[Cor_y]
871
		imul esi,edx
872
 
873
		movzx edx,byte[ecx+offs_cell_liv]
874
		and edx,3 ;ограничение
875
		shl edx,2
876
		add edx,shem_colors
877
 
878
		movzx ecx,byte[zoom]
879
		;;;dec ecx
880
		stdcall [buf2d_filled_rect_by_size], buf_0, edi, esi, ecx, ecx, [edx]
881
		add ebx,4
882
		cmp ebx,eax
883
		jle @b
884
 
885
	.no_draw:
886
	popad
887
	call p_paint_elems
888
	ret
889
endp
890
 
891
;Сортировка ячеек поля, нужна для более быстрого поиска
892
align 4
893
proc pole_sort uses eax edi, pole:dword
894
	mov edi,dword[pole]
895
	mov eax,pole_index
896
	mov eax,dword[eax] ;firstC -> eax
897
	stdcall pole_fl_sort, pole_index,eax ;сортируем все ячейки
898
	mov pole_b_sort,eax ;ставим число отсортированных ячеек равное числу всех существующих ячеек
899
	ret
900
endp
901
 
902
;Сортировка вектора a[1..n] методом Флойда
903
;Элемент a[0] в сортировке не участвует
904
align 4
905
proc pole_fl_sort uses eax ecx edx edi esi, a:dword, n:dword
906
	mov ecx,dword[a]
907
	;Формировать исходное частично упорядоченное дерево
908
	mov eax,dword[n]
909
	shr eax,1
910
	@@: ;for(i=n>>1; i>=2; i--)
911
		stdcall pole_fl_surface, ecx,eax,[n] ;(a,i,n)
912
		dec eax
913
		cmp eax,2
914
		jge @b
915
	;Выполнить процедуру всплытия Флойда для каждого поддерева
916
	mov eax,dword[n]
917
	@@: ;for(i=n; i>=2; i--){
918
		stdcall pole_fl_surface, ecx,1,eax ;(a,1,i)
919
		;Поместить найденный максимальный элемент в конец списка
920
		mov edi,eax
921
		shl edi,2
922
		add edi,ecx ;edi -> &a[i]
923
		mov esi,dword[edi] ;w=a[i];
924
		mov edx,dword[ecx+4]
925
		mov dword[edi],edx ;a[i]=a[1];
926
		mov dword[ecx+4],esi ;a[1]=w;
927
 
928
		dec eax
929
		cmp eax,2
930
		jge @b
931
	ret
932
endp
933
 
934
;Процедура всплытия Флойда по дереву a[1..k]
935
align 4
936
proc pole_fl_surface, a:dword, i:dword, k:dword
937
locals
938
	copy dd ?
939
endl
940
	pushad
941
	;edx -> ...
942
	;edi -> m
943
	;esi -> j
944
	mov eax,dword[a]
945
	mov ebx,dword[i]
946
	mov ecx,dword[k]
947
 
948
	mov edx,ebx
949
	shl edx,2
950
	add edx,eax
951
	mov edx,dword[edx]
952
	mov dword[copy],edx ;copy=a[i];
953
	mov edi,ebx
954
	shl edi,1 ;m=i<<1;
955
	.cycle_b: ;while (m<=k) {
956
		cmp edi,ecx
957
		jg .cycle_e
958
		jne @f ;if (m==k) j=m;
959
			mov esi,edi
960
			jmp .else_e
961
		@@: ;else if (pole_compare_cells_bm(a[m],a[m+1])) j=m;
962
		mov edx,edi
963
		shl edx,2
964
		add edx,eax
965
		stdcall pole_compare_cells_bm, dword[edx],dword[edx+4]
966
		cmp dl,0
967
		je @f
968
			mov esi,edi
969
			jmp .else_e
970
		@@: ;else j=m+1;
971
			mov esi,edi
972
			inc esi
973
		.else_e:
974
 
975
		;if (pole_compare_cells_bm(a[j],copy)) {
976
		mov edx,esi
977
		shl edx,2
978
		add edx,eax
979
		stdcall pole_compare_cells_bm, dword[edx],dword[copy]
980
		cmp dl,0
981
		je .cycle_e ;} else break; //выход из цикла
982
 
983
		mov edx,esi
984
		shl edx,2
985
		add edx,eax
986
		push dword[edx] ;push a[j];
987
		mov edx,ebx
988
		shl edx,2
989
		add edx,eax
990
		pop dword[edx] ;a[i]=a[j];
991
		mov ebx,esi ;i=j;
992
		mov edi,ebx
993
		shl edi,1 ;m=i<<1;
994
 
995
		jmp .cycle_b
996
	.cycle_e:
997
 
998
	;значения многих регистров уже не важны т. к. конец функции
999
	shl ebx,2
1000
	add eax,ebx
1001
	mov edx,dword[copy]
1002
	mov dword[eax],edx ;a[i]=copy;
1003
 
1004
	popad
1005
	ret
1006
endp
1007
;--------------------------------------
1008
 
1009
align 4
1010
proc pole_draw_pok uses eax ebx ecx edx edi esi, pole:dword
1011
	;mov edi,dword[pole]
1012
 
1013
	mov eax,4 ;рисование текста
2501 IgorA 1014
	mov ebx,400*65536+5
2462 IgorA 1015
	mov ecx,[sc.work_text]
1016
	or  ecx,0x80000000 ;or (1 shl 30)
1017
	mov edx,txt_zoom
1018
	;mov edi,[sc.work]
1019
	int 0x40
1020
 
1021
	add bx,9
1022
	mov edx,txt_osob
1023
	int 0x40
1024
 
1025
	add bx,9
1026
	mov edx,txt_info
1027
	int 0x40
1028
 
1029
	mov eax,47
1030
	movzx ecx,byte[zoom]
1031
	mov ebx,(2 shl 16)
2501 IgorA 1032
	mov edx,(400+6*9)*65536+5
2462 IgorA 1033
	mov esi,[sc.work_button_text]
1034
	or  esi,(1 shl 30)
1035
	mov edi,[sc.work_button]
1036
	int 0x40 ;масштаб
1037
 
1038
	mov edi,dword[pole]
1039
	mov ecx,pole_index
1040
	mov ecx,[ecx]
1041
	mov edi,[sc.work_button]
1042
	mov ebx,(5 shl 16)
1043
	add edx,(6*0)*65536+9
1044
	int 0x40 ;число точек
1045
	ret
1046
endp
1047
 
1048
align 4
1049
but_zoom_p:
1050
	cmp byte[zoom],16
1051
	jge @f
1052
		pushad
1053
		;вычисление сдвигов для поля, которые обеспечат центровку поля при увеличении масштаба
1054
		movzx ecx,byte[zoom]
1055
		xor edx,edx
1056
		mov eax,dword[buf_0.w]
1057
		shr eax,1 ;в eax половина ширины поля
1058
		mov ebx,eax ;делаем резервную копию eax
1059
		div ecx ;делим eax на текущий масштаб
1060
		xchg eax,ebx
1061
		xor edx,edx
1062
		inc ecx
1063
		div ecx ;делим eax на новый масштаб
1064
		sub ebx,eax ;вычисляется сдвиг поля который обеспечит центровку поля
1065
		sub dword[Cor_x],ebx ;сдвигаем поле зрения по оси x
1066
		xor ecx,ecx
1067
		mov cl,byte[zoom]
1068
		xor edx,edx
1069
		mov eax,dword[buf_0.h]
1070
		shr eax,1
1071
		mov ebx,eax
1072
		div ecx
1073
		xchg eax,ebx
1074
		xor edx,edx
1075
		inc ecx
1076
		div ecx
1077
		sub ebx,eax
1078
		sub dword[Cor_y],ebx ;сдвигаем поле зрения по оси y
1079
 
1080
		inc byte[zoom]
1081
		stdcall pole_draw_pok, pole
1082
		popad
1083
 
1084
		.buf_clear:
1085
			call redraw_pole
1086
	@@:
1087
	ret
1088
 
1089
align 4
1090
but_zoom_m:
1091
	cmp byte[zoom],1
1092
	jle @f
1093
		pushad
1094
		;вычисление сдвигов для поля, которые обеспечат центровку поля при уменьшении масштаба
1095
		movzx ecx,byte[zoom]
1096
		xor edx,edx
1097
		mov eax,dword[buf_0.w]
1098
		shr eax,1 ;в eax половина ширины поля
1099
		mov ebx,eax ;делаем резервную копию eax
1100
		div ecx ;делим eax на текущий масштаб
1101
		xchg eax,ebx
1102
		xor edx,edx
1103
		dec ecx
1104
		div ecx ;делим eax на новый масштаб
1105
		sub ebx,eax ;вычисляется сдвиг поля который обеспечит центровку поля
1106
		sub dword[Cor_x],ebx ;сдвигаем поле зрения по оси x
1107
		xor ecx,ecx
1108
		mov cl,byte[zoom]
1109
		xor edx,edx
1110
		mov eax,dword[buf_0.h]
1111
		shr eax,1
1112
		mov ebx,eax
1113
		div ecx
1114
		xchg eax,ebx
1115
		xor edx,edx
1116
		dec ecx
1117
		div ecx
1118
		sub ebx,eax
1119
		sub dword[Cor_y],ebx ;сдвигаем поле зрения по оси y
1120
 
1121
		dec byte[zoom]
1122
		stdcall pole_draw_pok, pole
1123
		popad
1124
 
1125
		.buf_clear:
1126
			call redraw_pole
1127
	@@:
1128
	ret
1129
 
1130
;центровка схемы по центру экрана
1131
align 4
1132
proc but_center uses eax ebx ecx edx
1133
	movzx ecx,byte[zoom]
1134
	cmp ecx,1
1135
	jle .end_m_1
1136
		mov eax,[buf_0.w]
1137
		mov ebx,[shem_w]
1138
		imul ebx,ecx
1139
 
1140
		sub eax,ebx
1141
		xor edx,edx
1142
		shl ecx,1
1143
		cmp eax,0
1144
		jge @f
1145
			neg eax
1146
			inc eax
1147
			div ecx
1148
			neg eax
1149
			inc eax
1150
			jmp .set_x
1151
		@@:
1152
			div ecx
1153
		.set_x:
1154
		mov [Cor_x],eax
1155
		mov eax,[buf_0.h]
1156
		mov ebx,[shem_h]
1157
		shr ecx,1
1158
		imul ebx,ecx
1159
		sub eax,ebx
1160
		xor edx,edx
1161
		shl ecx,1
1162
		cmp eax,0
1163
		jge @f
1164
			neg eax
1165
			inc eax
1166
			div ecx
1167
			neg eax
1168
			inc eax
1169
			jmp .set_y
1170
		@@:
1171
			div ecx
1172
		.set_y:
1173
		mov [Cor_y],eax
1174
		jmp .end_m_n
1175
	.end_m_1:
1176
		mov eax,[buf_0.w]
1177
		sub eax,[shem_w]
1178
		shr eax,1
1179
		bt eax,30
1180
		jnc @f
1181
			bts eax,31
1182
		@@:
1183
		mov [Cor_x],eax
1184
		mov eax,[buf_0.h]
1185
		sub eax,[shem_h]
1186
		shr eax,1
1187
		bt eax,30
1188
		jnc @f
1189
			bts eax,31
1190
		@@:
1191
		mov [Cor_y],eax
1192
	.end_m_n:
1193
	call redraw_pole
1194
	ret
1195
endp
1196
 
1197
align 4
1198
but_pole_up:
1199
	push eax ecx edx
1200
	mov eax,dword[buf_0.h]
1201
	shr eax,2
1202
	movzx ecx,byte[zoom]
1203
	cmp cx,2
1204
	jl @f ;деление на величину zoom
1205
		xor edx,edx
1206
		div ecx
1207
	@@:
1208
	add dword[Cor_y],eax
1209
	pop edx ecx eax
1210
	call redraw_pole
1211
	ret
1212
 
1213
align 4
1214
but_pole_dn:
1215
	push eax ecx edx
1216
	mov eax,dword[buf_0.h]
1217
	shr eax,2
1218
	xor ecx,ecx
1219
	mov cl,byte[zoom]
1220
	cmp cx,2
1221
	jl @f ;деление на величину zoom
1222
		xor edx,edx
1223
		div ecx
1224
	@@:
1225
	sub dword[Cor_y],eax
1226
	pop edx ecx eax
1227
	call redraw_pole
1228
	ret
1229
 
1230
align 4
1231
but_pole_left:
1232
	push eax ecx edx
1233
	mov eax,dword[buf_0.w]
1234
	shr eax,2
1235
	xor ecx,ecx
1236
	mov cl,byte[zoom]
1237
	cmp cx,2
1238
	jl @f ;деление на величину zoom
1239
		xor edx,edx
1240
		div ecx
1241
	@@:
1242
	add dword[Cor_x],eax
1243
	pop edx ecx eax
1244
	call redraw_pole
1245
	ret
1246
 
1247
align 4
1248
but_pole_right:
1249
	push eax ecx edx
1250
	mov eax,dword[buf_0.w]
1251
	shr eax,2
1252
	xor ecx,ecx
1253
	mov cl,byte[zoom]
1254
	cmp cx,2
1255
	jl @f ;деление на величину zoom
1256
		xor edx,edx
1257
		div ecx
1258
	@@:
1259
	sub dword[Cor_x],eax
1260
	pop edx ecx eax
1261
	call redraw_pole
1262
	ret
1263
 
1264
;output:
1265
; edx - count created points
1266
align 4
1267
proc shem_create_line uses eax ebx ecx edi, x:dword, y:dword, opt:dword
1268
	mov edi,pole
1269
	xor edx,edx
1270
 
1271
	mov ebx,[x]
1272
	mov ecx,[y]
1273
	bt dword[opt],0
1274
	jnc @f
1275
	.line_lr:
1276
		inc ebx
1277
		cmp ebx,[shem_w]
1278
		jge @f
1279
		stdcall pole_cell_find, pole,ebx,ecx
1280
		cmp eax,0
1281
		je .u0
1282
			imul eax,sizeof.Cell
1283
			add eax,pole_data
1284
			cmp byte[eax+offs_cell_liv],1
1285
			jne @f
1286
		.u0:
1287
		stdcall pole_cell_creat, pole,ebx,ecx,1
1288
		inc edx
1289
		jmp .line_lr
1290
	@@:
1291
 
1292
	mov ebx,[x]
1293
	;mov ecx,[y]
1294
	bt dword[opt],2
1295
	jnc @f
1296
	.line_rl:
1297
		dec ebx
1298
		cmp ebx,0
1299
		jl @f
1300
		stdcall pole_cell_find, pole,ebx,ecx
1301
		cmp eax,0
1302
		je .u1
1303
			imul eax,sizeof.Cell
1304
			add eax,pole_data
1305
			cmp byte[eax+offs_cell_liv],1
1306
			jne @f
1307
		.u1:
1308
		stdcall pole_cell_creat, pole,ebx,ecx,1
1309
		inc edx
1310
		jmp .line_rl
1311
	@@:
1312
 
1313
	mov ebx,[x]
1314
	mov ecx,[y]
1315
	bt dword[opt],3
1316
	jnc @f
1317
	.line_du:
1318
		dec ecx
1319
		cmp ecx,0
1320
		jl @f
1321
		stdcall pole_cell_find, pole,ebx,ecx
1322
		cmp eax,0
1323
		je .u2
1324
			imul eax,sizeof.Cell
1325
			add eax,pole_data
1326
			cmp byte[eax+offs_cell_liv],1
1327
			jne @f
1328
		.u2:
1329
		stdcall pole_cell_creat, pole,ebx,ecx,1
1330
		inc edx
1331
		jmp .line_du
1332
	@@:
1333
 
1334
	;mov ebx,[x]
1335
	mov ecx,[y]
1336
	bt dword[opt],1
1337
	jnc @f
1338
	.line_ud:
1339
		inc ecx
1340
		cmp ecx,[shem_h]
1341
		jge @f
1342
		stdcall pole_cell_find, pole,ebx,ecx
1343
		cmp eax,0
1344
		je .u3
1345
			imul eax,sizeof.Cell
1346
			add eax,pole_data
1347
			cmp byte[eax+offs_cell_liv],1
1348
			jne @f
1349
		.u3:
1350
		stdcall pole_cell_creat, pole,ebx,ecx,1
1351
		inc edx
1352
		jmp .line_ud
1353
	@@:
1354
 
1355
	ret
1356
endp
1357
 
1358
align 4
1359
redraw_pole:
1360
	stdcall [buf2d_clear], buf_0, [buf_0.color]
1361
	stdcall pole_paint, pole
1362
	stdcall [buf2d_draw], buf_0
1363
	ret