Subversion Repositories Kolibri OS

Rev

Rev 2487 | Rev 2507 | 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
 
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
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 ;рисование текста
2501 IgorA 981
	mov ebx,400*65536+5
2462 IgorA 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)
2501 IgorA 999
	mov edx,(400+6*9)*65536+5
2462 IgorA 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