Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1535 IgorA 1
format MS COFF
2
public EXPORTS
3
section '.flat' code readable align 16
4
 
5
include '../../../../macros.inc'
6
include '../../../../proc32.inc'
7
 
8
;-----------------------------------------------------------------------------
9
mem.alloc   dd ? ;функция для выделения памяти
10
mem.free    dd ? ;функция для освобождения памяти
11
mem.realloc dd ? ;функция для перераспределения памяти
12
dll.load    dd ?
13
 
14
BUF_STRUCT_SIZE equ 21
15
buf2d_data equ dword[edi] ;данные буфера изображения
16
buf2d_w equ dword[edi+8] ;ширина буфера
17
buf2d_h equ dword[edi+12] ;высота буфера
1538 IgorA 18
buf2d_l equ word[edi+4]
1535 IgorA 19
buf2d_t equ word[edi+6] ;отступ сверху
20
buf2d_size_lt equ dword[edi+4] ;отступ слева и справа для буфера
21
buf2d_color equ dword[edi+16] ;цвет фона буфера
22
buf2d_bits equ byte[edi+20] ;количество бит в 1-й точке изображения
23
 
24
struct buf_2d_header
25
	img_data dd ?
26
	left dw ? ;+4 left
27
	top dw ? ;+6 top
28
	size_x dd ? ;+8 w
29
	size_y dd ? ;+12 h
30
	color dd ? ;+16 color
31
	bit_pp db ? ;+21 bit in pixel
32
ends
33
 
34
macro swap v1, v2 {
35
  push v1
36
  push v2
37
  pop v1
38
  pop v2
39
}
40
 
41
;флаги, для функции обрезания буфера
42
BUF2D_OPT_CROP_TOP equ 1 ;обрезка сверху
43
BUF2D_OPT_CROP_LEFT equ 2 ;обрезка слева
44
BUF2D_OPT_CROP_BOTTOM equ 4 ;обрезка снизу
45
BUF2D_OPT_CROP_RIGHT equ 8 ;обрезка справа
46
BUF2D_BIT_OPT_CROP_TOP equ 0
47
BUF2D_BIT_OPT_CROP_LEFT equ 1
48
BUF2D_BIT_OPT_CROP_BOTTOM equ 2
49
BUF2D_BIT_OPT_CROP_RIGHT equ 3
50
 
2748 IgorA 51
vox_offs_tree_table equ 4
52
vox_offs_data equ 12
53
 
1535 IgorA 54
;input:
55
; eax = указатель на функцию выделения памяти
56
; ebx = ... освобождения памяти
57
; ecx = ... перераспределения памяти
58
; edx = ... загрузки библиотеки (пока не используется)
59
align 16
60
lib_init:
61
	mov dword[mem.alloc], eax
62
	mov dword[mem.free], ebx
63
	mov dword[mem.realloc], ecx
64
	mov dword[dll.load], edx
65
	ret
66
 
67
;input:
68
; ebx = coord x
69
; ecx = coord y
70
; edx = pixel color
71
; edi = pointer to buffer struct
72
align 4
73
draw_pixel:
74
	;cmp buf2d_bits,24
75
	;jne @f
76
	bt ebx,31
77
	jc @f
78
	bt ecx,31
79
	jc @f
80
	cmp ebx,buf2d_w
81
	jge @f
82
	cmp ecx,buf2d_h
83
	jge @f
84
	push esi
85
		mov esi,buf2d_w ;size x
86
		imul esi,ecx ;size_x*y
87
		add esi,ebx	 ;size_x*y+x
2358 IgorA 88
		cmp buf2d_bits,8
89
		je .beg8
2658 IgorA 90
		cmp buf2d_bits,32
91
		je .beg32
2358 IgorA 92
			lea esi,[esi+esi*2] ;(size_x*y+x)*3
93
			add esi,buf2d_data  ;ptr+(size_x*y+x)*3
94
			mov word[esi],dx ;copy pixel color
95
			ror edx,16
96
			mov byte[esi+2],dl
97
			ror edx,16
98
			jmp .end_draw
99
		.beg8: ;рисование точки в 8 битном буфере
100
			add esi,buf2d_data  ;ptr+(size_x*y+x)
101
			mov byte[esi],dl
2658 IgorA 102
			jmp .end_draw
103
		.beg32: ;рисование точки в 32 битном буфере
104
			shl esi,2
105
			add esi,buf2d_data  ;ptr+(size_x*y+x)
106
			mov dword[esi],edx
2358 IgorA 107
		.end_draw:
1535 IgorA 108
	pop esi
109
	@@:
110
	ret
111
 
1684 IgorA 112
;input:
113
; ebx = coord x
114
; ecx = coord y
115
; edi = pointer to buffer struct
116
;output:
117
; eax = цвет точки
118
; в случае ошибки eax = 0xffffffff
119
align 4
2658 IgorA 120
get_pixel_8:
121
	mov eax,0xffffffff
122
 
123
	bt ebx,31
124
	jc @f
125
	bt ecx,31
126
	jc @f
127
	cmp ebx,buf2d_w
128
	jge @f
129
	cmp ecx,buf2d_h
130
	jge @f
131
	push esi
132
		mov esi,buf2d_w ;size x
133
		imul esi,ecx ;size_x*y
134
		add esi,ebx	 ;size_x*y+x
135
		add esi,buf2d_data  ;ptr+(size_x*y+x)
136
 
137
		movzx eax,byte[esi] ;copy pixel color
138
	pop esi
139
	@@:
140
	ret
141
 
142
;input:
143
; ebx = coord x
144
; ecx = coord y
145
; edi = pointer to buffer struct
146
;output:
147
; eax = цвет точки
148
; в случае ошибки eax = 0xffffffff
149
align 4
1684 IgorA 150
get_pixel_24:
151
	mov eax,0xffffffff
152
 
153
	bt ebx,31
154
	jc @f
155
	bt ecx,31
156
	jc @f
157
	cmp ebx,buf2d_w
158
	jge @f
159
	cmp ecx,buf2d_h
160
	jge @f
161
	push esi
162
		mov esi,buf2d_w ;size x
163
		imul esi,ecx ;size_x*y
164
		add esi,ebx	 ;size_x*y+x
165
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
166
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
167
 
168
		xor eax,eax
169
		mov ax,word[esi] ;copy pixel color
170
		ror eax,16
171
		mov al,byte[esi+2]
172
		ror eax,16
173
	pop esi
174
	@@:
175
	ret
176
 
2230 IgorA 177
;input:
178
; ebx = coord x
179
; ecx = coord y
2658 IgorA 180
; edi = pointer to buffer struct
181
;output:
182
; eax = цвет точки
183
; в случае ошибки eax = 0xffffffff
184
align 4
185
get_pixel_32:
186
	mov eax,0xffffffff
187
 
188
	bt ebx,31
189
	jc @f
190
	bt ecx,31
191
	jc @f
192
	cmp ebx,buf2d_w
193
	jge @f
194
	cmp ecx,buf2d_h
195
	jge @f
196
	push esi
197
		mov esi,buf2d_w ;size x
198
		imul esi,ecx ;size_x*y
199
		add esi,ebx	 ;size_x*y+x
200
		shl esi,2
201
		add esi,buf2d_data  ;ptr+(size_x*y+x)*4
202
 
203
		mov eax,dword[esi] ;copy pixel color
204
	pop esi
205
	@@:
206
	ret
207
 
208
;input:
209
; ebx = coord x
210
; ecx = coord y
2230 IgorA 211
; edx = pixel color + transparent
212
; edi = pointer to buffer struct
213
; t_prop, m_prop - коэфициенты необходимые для вычисления степени прозрачности
214
align 4
215
transp_32 dd 0 ;цвет рисуемой точки + прозрачность
216
align 4
217
proc draw_pixel_transp, t_prop:dword, m_prop:dword
218
	;cmp buf2d_bits,24
219
	;jne @f
220
	bt ebx,31
221
	jc @f
222
	bt ecx,31
223
	jc @f
224
	cmp ebx,buf2d_w
225
	jge @f
226
	cmp ecx,buf2d_h
227
	jge @f
228
	push eax ebx edx edi esi
229
		mov esi,buf2d_w ;size x
230
		imul esi,ecx ;size_x*y
231
		add esi,ebx	 ;size_x*y+x
232
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
233
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
1684 IgorA 234
 
2230 IgorA 235
		mov edi,esi ;указатель на цвет фона
236
		mov dword[transp_32],edx ;цвет рисуемой точки
237
 
238
		xor edx,edx
239
		mov eax,[t_prop]
240
		shl eax,8 ;*=256
241
		mov ebx,[m_prop]
242
		div ebx ;вычисляем коэф. прозрачности (должен быть от 0 до 255)
243
		bt ax,8
244
		jnc .over_255
245
			;если коеф. прозрачности >=256 то уменьшаем его до 255
246
			mov al,0xff
247
		.over_255:
248
 
249
		mov byte[transp_32+3],al ;прозрачность рисуемой точки
250
		mov esi,dword transp_32 ;указатель на цвет рисуемой точки
251
 
252
		call combine_colors
253
	pop esi edi edx ebx eax
254
	@@:
255
	ret
256
endp
257
 
1535 IgorA 258
;создание буфера
259
align 4
260
proc buf_create, buf_struc:dword
261
	pushad
262
	mov edi,dword[buf_struc]
263
	mov ecx,buf2d_w
264
	mov ebx,buf2d_h
265
	imul ecx,ebx
266
	cmp buf2d_bits,24
267
	jne @f
268
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
269
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
270
	@@:
271
	cmp buf2d_bits,32
272
	jne @f
273
		shl ecx,2 ; 32 bit = 4
274
	@@:
275
	invoke mem.alloc,ecx
276
	mov buf2d_data,eax
277
 
278
	stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
279
	popad
280
	ret
281
endp
282
 
283
;создание буфера на основе изображения rgb
284
align 4
285
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
286
	pushad
287
	mov edi,dword[buf_struc]
288
	mov ecx,buf2d_w
289
	mov ebx,buf2d_h
290
	imul ecx,ebx
291
	cmp buf2d_bits,24
292
	jne @f
293
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
294
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
295
	@@:
296
	cmp buf2d_bits,32
297
	jne @f
298
		shl ecx,2 ; 32 bit = 4
299
	@@:
300
	invoke mem.alloc,ecx
301
	mov buf2d_data,eax
302
 
303
	cmp buf2d_bits,24
304
	jne @f
305
		cld
306
		mov esi,[rgb_data]
307
		mov edi,eax ;eax=buf2d_data
308
		rep movsb ;копируем биты изображения в буфер
309
		jmp .end_create
310
	@@:
311
		stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
312
	.end_create:
313
	popad
314
	ret
315
endp
316
 
317
align 4
318
proc buf_clear, buf_struc:dword, color:dword ;очистка буфера заданым цветом
319
	pushad
320
	mov edi,dword[buf_struc]
321
 
322
	mov ecx,buf2d_w
323
	mov ebx,buf2d_h
324
	imul ecx,ebx
325
 
326
	cld
327
 
328
	cmp buf2d_bits,8
329
	jne .end_clear_8
330
		mov edi,buf2d_data
331
		mov al,byte[color]
332
		rep stosb
333
		jmp .end_clear_32
334
	.end_clear_8:
335
 
336
	cmp buf2d_bits,24
337
	jne .end_clear_24
338
		mov edi,buf2d_data
339
		mov eax,dword[color]
340
		mov ebx,eax
341
		shr ebx,16
342
		@@:
343
			stosw
344
			mov byte[edi],bl
345
			inc edi
346
			loop @b
347
		jmp .end_clear_32
348
	.end_clear_24:
349
 
350
	cmp buf2d_bits,32
351
	jne .end_clear_32
352
		mov edi,buf2d_data
353
		mov eax,dword[color]
354
		rep stosd
355
		;jmp .end_clear_32
356
	.end_clear_32:
357
	popad
358
	ret
359
endp
360
 
1538 IgorA 361
;функция для обрезания буферов 8 и 24 битных, по заданому цвету.
362
;параметр opt задается комбинацией констант:
363
; BUF2D_OPT_CROP_TOP - обрезка сверху
364
; BUF2D_OPT_CROP_LEFT - обрезка слева
365
; BUF2D_OPT_CROP_BOTTOM - обрезка снизу
366
; BUF2D_OPT_CROP_RIGHT - обрезка справа
1535 IgorA 367
align 4
1538 IgorA 368
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
1535 IgorA 369
locals
370
	crop_r dd ?
371
endl
372
	pushad
373
	mov edi,dword[buf_struc]
374
	cmp buf2d_bits,24
375
	jne .24end_f
376
 
377
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
378
	jae .24no_crop_bottom
379
		mov eax,dword[color]
380
		mov edx,eax ;ax = colors - r,g
381
		shr edx,16 ;dl = color - b
382
		mov ecx,buf2d_h
1555 IgorA 383
		cmp ecx,1
384
		jle .24no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 385
		mov ebx,buf2d_w
386
		imul ecx,ebx
387
		lea esi,[ecx+ecx*2] ;esi=3*ecx
388
		add esi,buf2d_data
389
		cld
390
		@@:
391
			sub esi,3
392
			cmp word[esi],ax
393
			jne @f
394
			cmp byte[esi+2],dl
395
			jne @f
396
			loop @b
397
		@@:
398
		lea ebx,[ebx+ebx*2]
399
		xor edx,edx
400
		mov eax,buf2d_h
401
		imul eax,ebx
402
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
403
		@@:
404
			add esi,ebx
405
			cmp esi,eax
406
			jge @f
407
			inc edx ;вычисляем число полных строк для обрезания
408
			loop @b
409
		@@:
410
		cmp edx,0
411
		je .24no_crop_bottom
412
			cmp edx,buf2d_h
413
			jge .24no_crop_bottom ;что-бы не получить пустой буфер
414
			sub buf2d_h,edx ;уменьшаем высоту буфера
415
			mov ecx,buf2d_h
416
			imul ecx,ebx ;ecx = новый размер изображения
417
			invoke mem.realloc,buf2d_data,ecx
418
			mov buf2d_data,eax ;на случай если изменился указатель на данные
419
	.24no_crop_bottom:
420
 
421
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
422
	jae .24no_crop_top
423
		mov eax,dword[color]
424
		mov edx,eax ;ax = colors - r,g
425
		shr edx,16 ;dl = color - b
426
		mov esi,buf2d_data
427
		mov ecx,buf2d_h
1555 IgorA 428
		cmp ecx,1
429
		jle .24no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 430
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
431
		mov ebx,buf2d_w
432
		imul ecx,ebx
433
		cld
434
		@@:
435
			cmp word[esi],ax
436
			jne @f
437
			cmp byte[esi+2],dl
438
			jne @f
439
			add esi,3
440
			loop @b
441
		@@:
442
		lea ebx,[ebx+ebx*2]
443
		xor edx,edx
444
		@@:
445
			sub esi,ebx
446
			cmp esi,buf2d_data
447
			jl @f
448
			inc edx ;вычисляем число полных строк для обрезания
449
			loop @b
450
		@@:
451
		cmp edx,0
452
		je .24no_crop_top
453
			xor eax,eax
454
			sub eax,edx
455
			mov ebx,buf2d_h
456
			sub ebx,edx
457
			stdcall buf_offset_h, edi, eax, edx, ebx ;сдвигаем изображение в буфере вверх (eax<0)
458
			sub buf2d_h,edx ;уменьшаем высоту буфера
459
			mov ecx,buf2d_h
460
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
461
			mov ebx,buf2d_w
462
			imul ecx,ebx
463
			lea ecx,[ecx+ecx*2]
464
			invoke mem.realloc,buf2d_data,ecx
465
			mov buf2d_data,eax ;на случай если изменился указатель на данные
466
	.24no_crop_top:
467
 
468
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
469
	jae .24no_crop_right
470
		mov eax,dword[color]
471
		mov edx,eax ;ax = colors - r,g
472
		shr edx,16 ;dl = color - b
473
		mov ebx,buf2d_w
1555 IgorA 474
		cmp ebx,1
475
		jle .24no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 476
		lea ebx,[ebx+ebx*2]
477
		mov esi,ebx
478
		imul esi,buf2d_h
479
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
480
		mov dword[crop_r],0
481
		cld
1538 IgorA 482
		.24found_beg_right:
1535 IgorA 483
		sub esi,3 ;двигаемся на 1-ну колонку влево
484
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
485
		@@:
486
			cmp word[esi],ax
1538 IgorA 487
			jne .24found_right
1535 IgorA 488
			cmp byte[esi+2],dl
1538 IgorA 489
			jne .24found_right
1535 IgorA 490
			sub esi,ebx ;прыгаем на верхнюю строку
491
			loop @b
492
		inc dword[crop_r]
493
 
494
		mov ecx,buf2d_w
495
		dec ecx ;1 колонка на запас
496
		cmp dword[crop_r],ecx
1538 IgorA 497
		jge .24found_right
1535 IgorA 498
 
499
		sub esi,3 ;двигаемся на 1-ну колонку влево
500
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
501
		@@:
502
			add esi,ebx ;прыгаем на нижнюю строку
503
			cmp word[esi],ax
1538 IgorA 504
			jne .24found_right
1535 IgorA 505
			cmp byte[esi+2],dl
1538 IgorA 506
			jne .24found_right
1535 IgorA 507
			loop @b
508
		inc dword[crop_r]
509
 
510
		mov ecx,buf2d_w
511
		dec ecx ;1 колонка на запас
512
		cmp dword[crop_r],ecx
1538 IgorA 513
		jl .24found_beg_right
1535 IgorA 514
 
1538 IgorA 515
		.24found_right:
1535 IgorA 516
		cmp dword[crop_r],0
517
		je .24no_crop_right
518
			mov ecx,buf2d_w
519
			sub ecx,dword[crop_r]
1538 IgorA 520
			stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 521
			mov buf2d_w,ecx ;ставим новую ширину для буфера
522
			mov ebx,buf2d_h
523
			imul ecx,ebx
524
			lea ecx,[ecx+ecx*2]
525
			invoke mem.realloc,buf2d_data,ecx
526
			mov buf2d_data,eax ;на случай если изменился указатель на данные
527
	.24no_crop_right:
528
 
1538 IgorA 529
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
530
	jae .24no_crop_left
531
		mov eax,dword[color]
532
		mov edx,eax ;ax = colors - r,g
533
		shr edx,16 ;dl = color - b
534
		mov ebx,buf2d_w
1555 IgorA 535
		cmp ebx,1
536
		jle .24no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 537
		lea ebx,[ebx+ebx*2]
538
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
539
		mov dword[crop_r],0
540
		cld
541
		.24found_beg_left:
542
 
543
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
544
		@@:
545
			cmp word[esi],ax
546
			jne .24found_left
547
			cmp byte[esi+2],dl
548
			jne .24found_left
549
			add esi,ebx ;прыгаем на нижнюю строку
550
			loop @b
551
		inc dword[crop_r]
552
		add esi,3 ;двигаемся на 1-ну колонку вправо
553
 
554
		mov ecx,buf2d_w
555
		dec ecx ;1 колонка на запас
556
		cmp dword[crop_r],ecx
557
		jge .24found_left
558
 
559
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
560
		@@:
561
			sub esi,ebx ;прыгаем на верхнюю строку
562
			cmp word[esi],ax
563
			jne .24found_left
564
			cmp byte[esi+2],dl
565
			jne .24found_left
566
			loop @b
567
		inc dword[crop_r]
568
		add esi,3 ;двигаемся на 1-ну колонку вправо
569
 
570
		mov ecx,buf2d_w
571
		dec ecx ;1 колонка на запас
572
		cmp dword[crop_r],ecx
573
		jl .24found_beg_left
574
 
575
		.24found_left:
576
		cmp dword[crop_r],0
577
		je .24no_crop_left
578
			mov ecx,buf2d_w
579
			sub ecx,dword[crop_r]
580
			stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
581
			mov buf2d_w,ecx ;ставим новую ширину для буфера
582
			mov ebx,buf2d_h
583
			imul ecx,ebx
584
			lea ecx,[ecx+ecx*2]
585
			invoke mem.realloc,buf2d_data,ecx
586
			mov buf2d_data,eax ;на случай если изменился указатель на данные
587
			mov eax,dword[crop_r]
588
			add buf2d_l,ax
589
	.24no_crop_left:
590
 
1535 IgorA 591
	.24end_f:
592
 
593
 
594
	cmp buf2d_bits,8
595
	jne .8end_f
596
 
597
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
598
	jae .8no_crop_bottom
599
		mov eax,dword[color]
600
		mov esi,buf2d_data
601
		mov ecx,buf2d_h
1555 IgorA 602
		cmp ecx,1
603
		jle .8no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 604
		mov ebx,buf2d_w
605
		imul ecx,ebx
606
		mov esi,ecx
607
		add esi,buf2d_data
608
		cld
609
		@@:
610
			dec esi
611
			cmp byte[esi],al
612
			jne @f
613
			loop @b
614
		@@:
615
		xor edx,edx
616
		mov eax,buf2d_h
617
		imul eax,ebx
618
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
619
		@@:
620
			add esi,ebx
621
			cmp esi,eax
622
			jge @f
623
			inc edx
624
			loop @b
625
		@@:
626
		cmp edx,0
627
		je .8no_crop_bottom
628
			cmp edx,buf2d_h
629
			jge .8no_crop_bottom ;что-бы не получить пустой буфер
630
			sub buf2d_h,edx ;уменьшаем высоту буфера
631
			mov ecx,buf2d_h
632
			imul ecx,ebx ;ecx = новый размер изображения
633
			invoke mem.realloc,buf2d_data,ecx
634
			mov buf2d_data,eax ;на случай если изменился указатель на данные
635
	.8no_crop_bottom:
636
 
637
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
638
	jae .8no_crop_top
639
		mov eax,dword[color]
640
		mov esi,buf2d_data
641
		mov ecx,buf2d_h
1555 IgorA 642
		cmp ecx,1
643
		jle .8no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 644
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
645
		mov ebx,buf2d_w
646
		imul ecx,ebx
647
		cld
648
		@@:
649
			cmp byte[esi],al
650
			jne @f
651
			inc esi
652
			loop @b
653
		@@:
654
		xor edx,edx
655
		@@:
656
			sub esi,ebx
657
			cmp esi,buf2d_data
658
			jl @f
659
			inc edx
660
			loop @b
661
		@@:
662
		cmp edx,0
663
		je .8no_crop_top
664
			xor eax,eax
665
			sub eax,edx
666
			mov ebx,buf2d_h
667
			sub ebx,edx
668
			stdcall buf_offset_h, edi, eax, edx, ebx
669
			mov ecx,buf2d_h
670
			sub ecx,edx
671
			mov buf2d_h,ecx ;уменьшаем высоту буфера
672
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
673
			mov ebx,buf2d_w
674
			imul ecx,ebx
675
			invoke mem.realloc,buf2d_data,ecx
676
			mov buf2d_data,eax ;на случай если изменился указатель на данные
677
	.8no_crop_top:
678
 
679
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
680
	jae .8no_crop_right
681
		mov eax,dword[color]
682
		mov ebx,buf2d_w
1555 IgorA 683
		cmp ebx,1
684
		jle .8no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 685
		mov esi,ebx
686
		imul esi,buf2d_h
687
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
688
		xor edx,edx
689
		cld
690
 
691
		.8found_beg:
692
		dec esi ;двигаемся на 1-ну колонку влево
693
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
694
		@@:
695
			cmp byte[esi],al
696
			jne .8found
697
			sub esi,ebx ;прыгаем на верхнюю строку
698
			loop @b
699
		inc edx
700
		mov ecx,buf2d_w
701
		dec ecx ;1 колонка на запас
702
		cmp edx,ecx
703
		jge .8found
704
 
705
		dec esi ;двигаемся на 1-ну колонку влево
706
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
707
		@@:
708
			add esi,ebx ;прыгаем на нижнюю строку
709
			cmp byte[esi],al
710
			jne .8found
711
			loop @b
712
		inc edx
713
 
714
		mov ecx,buf2d_w
715
		dec ecx ;1 колонка на запас
716
		cmp edx,ecx
717
		jl .8found_beg
718
 
719
		.8found:
720
		cmp edx,0
721
		je .8no_crop_right
722
			mov ecx,buf2d_w
723
			sub ecx,edx
1538 IgorA 724
			stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 725
			mov buf2d_w,ecx ;ставим новую ширину для буфера
726
			mov ebx,buf2d_h
727
			imul ecx,ebx
728
			invoke mem.realloc,buf2d_data,ecx
729
			mov buf2d_data,eax ;на случай если изменился указатель на данные
730
	.8no_crop_right:
731
 
1538 IgorA 732
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
733
	jae .8no_crop_left
734
		mov eax,dword[color]
735
		mov ebx,buf2d_w
1555 IgorA 736
		cmp ebx,1
737
		jle .8no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 738
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
739
		mov edx,0
740
		cld
741
		.8found_beg_left:
742
 
743
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
744
		@@:
745
			cmp word[esi],ax
746
			jne .8found_left
747
			add esi,ebx ;прыгаем на нижнюю строку
748
			loop @b
749
		inc edx
750
		inc esi ;двигаемся на 1-ну колонку вправо
751
 
752
		mov ecx,buf2d_w
753
		dec ecx ;1 колонка на запас
754
		cmp edx,ecx
755
		jge .8found_left
756
 
757
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
758
		@@:
759
			sub esi,ebx ;прыгаем на верхнюю строку
760
			cmp word[esi],ax
761
			jne .8found_left
762
			loop @b
763
		inc edx
764
		inc esi ;двигаемся на 1-ну колонку вправо
765
 
766
		mov ecx,buf2d_w
767
		dec ecx ;1 колонка на запас
768
		cmp edx,ecx
769
		jl .8found_beg_left
770
 
771
		.8found_left:
772
		cmp edx,0
773
		je .8no_crop_left
774
			mov ecx,buf2d_w
775
			sub ecx,edx
776
			stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
777
			mov buf2d_w,ecx ;ставим новую ширину для буфера
778
			mov ebx,buf2d_h
779
			imul ecx,ebx
780
			invoke mem.realloc,buf2d_data,ecx
781
			mov buf2d_data,eax ;на случай если изменился указатель на данные
782
			mov eax,edx
783
			add buf2d_l,ax
784
	.8no_crop_left:
785
 
1535 IgorA 786
	.8end_f:
787
 
788
	popad
789
	ret
790
endp
791
 
1538 IgorA 792
;обрезаем цветное изображение с правой стороны
1535 IgorA 793
;input:
794
;data_rgb - pointer to rgb data
795
;size_w_old - width img in pixels
796
;size_w_new - new width img in pixels
797
;size_h - height img in pixels
798
align 4
1538 IgorA 799
proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 800
	pushad
801
	mov eax, dword[size_w_old]
802
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
803
	mov ebx, dword[size_w_new]
804
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
805
	mov edx, dword[size_h]
806
	mov edi, dword[data_rgb] ;edi - получает данные
807
	mov esi, edi
808
	add edi, ebx
809
	add esi, eax
810
	cld
811
	@@:
812
		dec edx ;уменьшаем счетчик оставшихся строк на 1
813
		cmp edx,0
814
		jle @f
815
		mov ecx, ebx
816
		rep movsb ;перенос (копирование) строки пикселей
817
		add esi,eax ;переход на новую строчку изображения
818
		sub esi,ebx
819
		jmp @b
820
	@@:
821
	popad
822
	ret
823
endp
824
 
1538 IgorA 825
;обрезаем серое изображение с правой стороны
1535 IgorA 826
;input:
827
;data_gray - pointer to gray data
828
;size_w_old - width img in pixels
829
;size_w_new - new width img in pixels
830
;size_h - height img in pixels
831
align 4
1538 IgorA 832
proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 833
	pushad
834
	mov eax, dword[size_w_old]
835
	mov ebx, dword[size_w_new]
836
	mov edx, dword[size_h]
837
	mov edi, dword[data_gray] ;edi - получает данные
838
	mov esi, edi
839
	add edi, ebx
840
	add esi, eax
841
	cld
842
	@@:
843
		dec edx ;уменьшаем счетчик оставшихся строк на 1
844
		cmp edx,0
845
		jle @f
846
		mov ecx, ebx
847
		rep movsb ;перенос (копирование) строки пикселей
848
		add esi,eax ;переход на новую строчку изображения
849
		sub esi,ebx
850
		jmp @b
851
	@@:
852
	popad
853
	ret
854
endp
855
 
1538 IgorA 856
;обрезаем цветное изображение с левой стороны
857
;input:
858
;data_rgb - pointer to rgb data
859
;size_w_old - width img in pixels
860
;size_w_new - new width img in pixels
861
;size_h - height img in pixels
862
align 4
863
proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
864
	pushad
865
	mov edi,dword[data_rgb]
866
	mov esi,edi
867
	mov eax,dword[size_w_old]
868
	mov ebx,dword[size_w_new]
869
	cmp eax,ebx
870
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
871
		lea eax,[eax+eax*2]
872
		lea ebx,[ebx+ebx*2]
873
		sub eax,ebx
874
		mov edx,dword[size_h] ;высота изображения
875
		cld
876
		@@:
877
			add esi,eax
878
			mov ecx,ebx
879
			rep movsb
880
			dec edx
881
			cmp edx,0
882
			jg @b
883
	.end_f:
884
	popad
885
	ret
886
endp
887
 
888
;обрезаем серое изображение с левой стороны
889
;input:
890
;data_gray - pointer to gray data
891
;size_w_old - width img in pixels
892
;size_w_new - new width img in pixels
893
;size_h - height img in pixels
894
align 4
895
proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
896
	pushad
897
	mov edi,dword[data_gray]
898
	mov esi,edi
899
	mov eax,dword[size_w_old]
900
	mov ebx,dword[size_w_new]
901
	cmp eax,ebx
902
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
903
		sub eax,ebx
904
		mov edx,dword[size_h] ;высота изображения
905
		cld
906
		@@:
907
			add esi,eax
908
			mov ecx,ebx
909
			rep movsb
910
			dec edx
911
			cmp edx,0
912
			jg @b
913
	.end_f:
914
	popad
915
	ret
916
endp
917
 
1535 IgorA 918
;hoffs - колличество пикселей на котрые поднимается/опускается изображение
919
;img_t - высота, с которой начинается двигающаяся часть изображения
920
align 4
921
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;сдвигает изображение по высоте
922
	pushad
923
	mov edi,dword[buf_struc]
924
	cmp buf2d_bits,24
925
	jne .end_move_24
926
 
927
	mov eax,[hoffs]
928
	cmp eax,0
929
	je .end_move_24
930
		mov ebx,buf2d_w
931
		mov edx,dword[img_t]
932
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
933
			cmp ecx,buf2d_h
934
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
935
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
936
			lea ecx,[ecx+ecx*2]
937
		imul ebx,edx
938
		lea ebx,[ebx+ebx*2]
939
		mov esi,buf2d_data
940
		add esi,ebx
941
 
942
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
943
		mov ebx,buf2d_w
944
		imul ebx,edx
945
		lea ebx,[ebx+ebx*2]
946
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
947
		add edi,ebx
948
 
949
		cmp eax,0
950
		jg .move_down_24
951
			;двигаем изображение вверх
952
			cld
953
			rep movsb
954
			jmp .end_f
955
		.move_down_24:
956
			;двигаем изображение вниз
957
			add esi,ecx
958
			dec esi
959
			add edi,ecx
960
			dec edi
961
			std
962
			rep movsb
963
			jmp .end_f
964
	.end_move_24:
965
 
966
;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b
967
 
968
	cmp buf2d_bits,8
969
	jne .end_move_8
970
 
971
	mov eax,[hoffs]
972
	cmp eax,0
973
	je .end_move_8
974
		;двигаем изображение вверх
975
		mov ebx,buf2d_w
976
		mov edx,dword[img_t]
977
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
978
			cmp ecx,buf2d_h
979
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
980
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
981
		imul ebx,edx
982
		mov esi,buf2d_data
983
		add esi,ebx
984
 
985
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
986
		mov ebx,buf2d_w
987
		imul ebx,edx
988
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
989
		add edi,ebx
990
 
991
		cmp eax,0
992
		jg .move_down_8
993
			cld
994
			rep movsb
995
			jmp .end_f
996
		.move_down_8:
997
			;двигаем изображение вниз
998
			add esi,ecx
999
			dec esi
1000
			add edi,ecx
1001
			dec edi
1002
			std
1003
			rep movsb
1004
			jmp .end_f
1005
	.end_move_8:
1006
 
1007
	.end_f:
1008
	popad
1009
	ret
1010
endp
1011
 
1012
 
1013
align 4
1014
proc buf_draw_buf, buf_struc:dword
1015
	pushad
1016
	mov edi,dword[buf_struc]
1017
	cmp buf2d_bits,24
1018
	jne .error
1019
		mov eax,7
1020
		mov ebx,buf2d_data
1021
 
1022
		mov ecx,buf2d_w
1023
		ror ecx,16
1024
		mov edx,buf2d_h
1025
		mov cx,dx
1026
 
1027
		mov edx,buf2d_size_lt
1028
		ror edx,16
1029
		int 0x40
1030
		jmp .end_draw_24
1031
	.error:
1032
		stdcall print_err,sz_buf2d_draw,txt_err_n24b
1033
	.end_draw_24:
1034
	popad
1035
	ret
1036
endp
1037
 
1038
align 4
1039
proc buf_delete, buf_struc:dword
2136 IgorA 1040
	push eax edi
1535 IgorA 1041
	mov edi,dword[buf_struc]
1042
	invoke mem.free,buf2d_data
2136 IgorA 1043
	pop edi eax
1535 IgorA 1044
	ret
1045
endp
1046
 
1047
align 4
2136 IgorA 1048
proc buf_resize, buf_struc:dword, new_w:dword, new_h:dword
1049
	pushad
1050
	mov edi,dword[buf_struc]
1051
	cmp buf2d_bits,24
1052
	jne .24bit
1053
		mov eax,dword[new_w]
1054
		cmp eax,1
1055
		jl @f
1056
			mov buf2d_w,eax
1057
		@@:
1058
		mov ecx,buf2d_w
1059
		mov eax,dword[new_h]
1060
		cmp eax,1
1061
		jl @f
1062
			mov buf2d_h,eax
1063
		@@:
1064
		mov ebx,buf2d_h
1065
		imul ecx,ebx
1066
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
1067
		invoke mem.realloc,buf2d_data,ecx ;изменяем память занимаемую буфером
1068
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1069
	.24bit:
1070
	popad
1071
	ret
1072
endp
1073
 
1074
align 4
1535 IgorA 1075
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1076
locals
1077
	loc_1 dd ?
1078
	loc_2 dd ?
1079
	napravl db ?
1080
endl
1081
	pushad
1082
		mov eax,dword[coord_x1]
1083
		sub eax,dword[coord_x0]
1084
		bt eax,31
1085
		jae @f
1086
			neg eax
1087
			inc eax
1088
		@@:
1089
		mov ebx,dword[coord_y1]
1090
		sub ebx,dword[coord_y0]
2230 IgorA 1091
		jnz @f
1092
			;если задана горизонтальная линия y0=y1
1093
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1094
			jmp .coord_end
1095
		@@:
1535 IgorA 1096
		bt ebx,31
1097
		jae @f
1098
			neg ebx
1099
			inc ebx
1100
		@@:
2230 IgorA 1101
		mov edx,dword[color]
1535 IgorA 1102
 
1103
		mov [napravl],byte 0 ;bool steep=false
1104
		cmp eax,ebx
1105
		jle @f
1106
			mov [napravl],byte 1 ;bool steep=true
1107
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1108
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1109
		@@:
1110
		mov eax,dword[coord_y0] ;x0
1111
		cmp eax,dword[coord_y1] ;if(x0>x1)
1112
		jle @f
1113
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1114
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1115
		@@:
1116
 
1117
; int deltax esi
1118
; int deltay edi
1119
; int error  ebp-6
1120
; int ystep  ebp-8
1121
 
1122
		mov eax,dword[coord_y0]
1123
		mov esi,dword[coord_y1]
1124
		sub esi,eax ;deltax = y1-y0
1125
		mov ebx,esi
1126
		shr ebx,1
1127
		mov [loc_1],ebx ;error = deltax/2
1128
 
1129
		mov eax,dword[coord_x0]
1130
		mov edi,dword[coord_x1]
1131
		mov [loc_2],dword -1 ;ystep = -1
1132
		cmp eax,edi ;if (x0
1133
		jge @f
1134
			mov [loc_2],dword 1 ;ystep = 1
1135
		@@:
1136
		sub edi,eax ;x1-x0
1137
 
1138
		bts edi,31
1139
		jae @f
1140
			neg edi
1141
			inc edi
1142
		@@:
1143
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1144
 
1145
		mov eax,edi
1146
		mov edi,[buf_struc]
2358 IgorA 1147
		cmp buf2d_bits,8
1148
		je @f
1535 IgorA 1149
		cmp buf2d_bits,24
2358 IgorA 1150
		je @f
1151
			jmp .coord_end
1152
		@@:
1535 IgorA 1153
 
1154
		cmp [napravl],0
1155
		jne .coord_yx
1156
			mov ebx,dword[coord_x0]
1157
			mov ecx,dword[coord_y0]
1158
 
1159
			@@: ;for (x=x0 ; x
1160
				cmp ecx,dword[coord_y1]
1161
				jg @f ;jge ???
1162
				call draw_pixel
1163
 
1164
				sub dword[loc_1],eax ;error -= deltay
1165
				cmp dword[loc_1],0 ;if(error<0)
1166
				jge .if0
1167
					add ebx,[loc_2] ;y += ystep
1168
					add [loc_1],esi ;error += deltax
1169
				.if0:
1170
				inc ecx
1171
				jmp @b
1172
			@@:
1173
			jmp .coord_end
1174
		.coord_yx:
1175
			mov ebx,dword[coord_y0]
1176
			mov ecx,dword[coord_x0]
1177
 
1178
			@@: ;for (x=x0 ; x
1179
				cmp ebx,dword[coord_y1]
1180
				jg @f ;jge ???
1181
				call draw_pixel
1182
 
1183
				sub dword[loc_1],eax ;error -= deltay
1184
				cmp dword[loc_1],0 ;if(error<0)
1185
				jge .if1
1186
					add ecx,[loc_2] ;y += ystep
1187
					add [loc_1],esi ;error += deltax
1188
				.if1:
1189
				inc ebx
1190
				jmp @b
1191
			@@:
1192
	.coord_end:
1193
	popad
1194
	ret
1195
endp
1196
 
2230 IgorA 1197
;рисование сглаженной линии
1198
align 4
1199
proc buf_line_brs_sm, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1200
locals
1201
	loc_1 dd ?
1202
	loc_2 dd ?
1203
	napravl db ?
1204
endl
1205
	pushad
1206
		mov eax,dword[coord_x1]
1207
		sub eax,dword[coord_x0]
1208
		bt eax,31
1209
		jae @f
1210
			neg eax
1211
			inc eax
1212
		@@:
1213
		mov ebx,dword[coord_y1]
1214
		sub ebx,dword[coord_y0]
1215
		jnz @f
1216
			;если задана горизонтальная линия y0=y1
1217
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1218
			jmp .coord_end
1219
		@@:
1220
		bt ebx,31
1221
		jae @f
1222
			neg ebx
1223
			inc ebx
1224
		@@:
1225
		mov edx,dword[color]
1226
 
1227
		mov [napravl],byte 0 ;bool steep=false
1228
		cmp eax,ebx
1229
		jle @f
1230
			mov [napravl],byte 1 ;bool steep=true
1231
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1232
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1233
		@@:
1234
		mov eax,dword[coord_y0] ;x0
1235
		cmp eax,dword[coord_y1] ;if(x0>x1)
1236
		jle @f
1237
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1238
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1239
		@@:
1240
 
1241
; int deltax esi
1242
; int deltay edi
1243
; int error  ebp-6
1244
; int ystep  ebp-8
1245
 
1246
		mov eax,dword[coord_y0]
1247
		mov esi,dword[coord_y1]
1248
		sub esi,eax ;deltax = y1-y0
1249
		mov ebx,esi
1250
		shr ebx,1
1251
		mov [loc_1],ebx ;error = deltax/2
1252
 
1253
		mov eax,dword[coord_x0]
1254
		mov edi,dword[coord_x1]
1255
		mov [loc_2],dword -1 ;ystep = -1
1256
		cmp eax,edi ;if (x0
1257
		jge @f
1258
			mov [loc_2],dword 1 ;ystep = 1
1259
		@@:
1260
		sub edi,eax ;x1-x0
1261
 
1262
		bts edi,31
1263
		jae @f
1264
			neg edi
1265
			inc edi
1266
		@@:
1267
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1268
 
1269
		mov eax,edi
1270
		mov edi,[buf_struc]
1271
		cmp buf2d_bits,24
1272
		jne .coord_end
1273
 
1274
		cmp [napravl],0
1275
		jne .coord_yx
1276
			mov ebx,dword[coord_x0]
1277
			mov ecx,dword[coord_y0]
1278
 
1279
			@@: ;for (x=x0 ; x
1280
				cmp ecx,dword[coord_y1]
1281
				jg @f ;jge ???
1282
				push eax
1283
					mov eax,esi
1284
					sub eax,[loc_1]
1285
					stdcall draw_pixel_transp, eax,esi
1286
				pop eax
1287
				add ebx,[loc_2]
1288
				stdcall draw_pixel_transp, [loc_1],esi
1289
				sub ebx,[loc_2]
1290
 
1291
				sub dword[loc_1],eax ;error -= deltay
1292
				cmp dword[loc_1],0 ;if(error<0)
1293
				jge .if0
1294
					add ebx,[loc_2] ;y += ystep
1295
					add [loc_1],esi ;error += deltax
1296
				.if0:
1297
				inc ecx
1298
				jmp @b
1299
			@@:
1300
			jmp .coord_end
1301
		.coord_yx:
1302
			mov ebx,dword[coord_y0]
1303
			mov ecx,dword[coord_x0]
1304
 
1305
			@@: ;for (x=x0 ; x
1306
				cmp ebx,dword[coord_y1]
1307
				jg @f ;jge ???
1308
				push eax
1309
					mov eax,esi
1310
					sub eax,[loc_1]
1311
					stdcall draw_pixel_transp, eax,esi
1312
				pop eax
1313
				add ecx,[loc_2]
1314
				stdcall draw_pixel_transp, [loc_1],esi
1315
				sub ecx,[loc_2]
1316
 
1317
				sub dword[loc_1],eax ;error -= deltay
1318
				cmp dword[loc_1],0 ;if(error<0)
1319
				jge .if1
1320
					add ecx,[loc_2] ;y += ystep
1321
					add [loc_1],esi ;error += deltax
1322
				.if1:
1323
				inc ebx
1324
				jmp @b
1325
			@@:
1326
	.coord_end:
1327
	popad
1328
	ret
1329
endp
1330
 
1653 IgorA 1331
;рисование горизонтальной линии, потому нет параметра coord_y1
1535 IgorA 1332
align 4
1634 IgorA 1333
proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
1334
	pushad
2358 IgorA 1335
	pushfd
1634 IgorA 1336
		mov edi,[buf_struc]
2358 IgorA 1337
		cmp buf2d_bits,8
1338
		je @f
1634 IgorA 1339
		cmp buf2d_bits,24
2358 IgorA 1340
		je @f
1341
			jmp .end24
1342
		@@: ;определение координат линии относительно буфера
1634 IgorA 1343
 
2177 IgorA 1344
		mov ecx,dword[coord_y0]
1345
		bt ecx,31
1346
		jc .end24 ;если координата y0 отрицательная
1347
		cmp ecx,buf2d_h
1348
		jge .end24 ;если координата y0 больше высоты буфера
1349
 
1634 IgorA 1350
		mov ebx,dword[coord_x0]
1351
		mov esi,dword[coord_x1]
1717 IgorA 1352
		cmp ebx,esi
1353
		jle @f
1354
			xchg ebx,esi ;если x0 > x1 то меняем местами x0 и x1
2177 IgorA 1355
		@@:
2185 IgorA 1356
		bt ebx,31
1357
		jae @f
1358
			;если координата x0 отрицательная
1359
			xor ebx,ebx
1360
		@@:
2177 IgorA 1361
		cmp esi,buf2d_w
1362
		jl @f
2185 IgorA 1363
			;если координата x0 больше ширины буфера
2177 IgorA 1364
			mov esi,buf2d_w
2359 IgorA 1365
			dec esi
2177 IgorA 1366
		@@:
2185 IgorA 1367
		cmp ebx,esi
2358 IgorA 1368
		jg .end24 ;если x0 > x1 может возникнуть когда обе координаты x0, x1 находились за одним из пределов буфера
1717 IgorA 1369
 
2358 IgorA 1370
		cmp buf2d_bits,24
1371
		je .beg24
1372
			;рисование в 8 битном буфере
1373
			;в edx вычисляем начало 1-й точки линии в буфере изображения
1374
			mov edx,buf2d_w ;size x
1375
			imul edx,ecx ;size_x*y
1376
			add edx,ebx	 ;size_x*y+x
1377
			add edx,buf2d_data ;ptr+(size_x*y+x)
1378
			mov edi,edx ;теперь можем портить указатель на буфер
1379
 
1380
			mov ecx,esi
1381
			sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
1382
			inc ecx ;что-бы последняя точка линии также отображалась
1383
			mov eax,dword[color] ;будем использовать только значение в al
1384
			cld
1385
			rep stosb ;цикл по оси x от x0 до x1 (включая x1)
1386
			jmp .end24
1387
 
1388
		.beg24: ;рисование в 24 битном буфере
2177 IgorA 1389
		;в eax вычисляем начало 1-й точки линии в буфере изображения
1390
		mov eax,buf2d_w ;size x
1391
		imul eax,ecx ;size_x*y
1392
		add eax,ebx	 ;size_x*y+x
1393
		lea eax,[eax+eax*2] ;(size_x*y+x)*3
1394
		add eax,buf2d_data  ;ptr+(size_x*y+x)*3
1395
 
2185 IgorA 1396
		mov ecx,esi
1397
		sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
2358 IgorA 1398
		inc ecx ;что-бы последняя точка линии также отображалась
2177 IgorA 1399
		mov edx,dword[color]
2185 IgorA 1400
		mov ebx,edx ;координата x0 в ebx уже не нужна
1401
		ror edx,16 ;поворачиваем регистр что бы 3-й байт попал в dl
1402
		cld
2358 IgorA 1403
		@@: ;цикл по оси x от x0 до x1 (включая x1)
2185 IgorA 1404
			mov word[eax],bx ;copy pixel color
1405
			mov byte[eax+2],dl
1406
			add eax,3
1407
			loop @b
1684 IgorA 1408
		.end24:
2358 IgorA 1409
	popfd
1634 IgorA 1410
	popad
1411
	ret
1412
endp
1413
 
1414
align 4
1415
proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1416
pushad
1417
	mov edi,[buf_struc]
2358 IgorA 1418
	cmp buf2d_bits,8
1419
	je @f
1634 IgorA 1420
	cmp buf2d_bits,24
2358 IgorA 1421
	je @f
1422
		jmp .coord_end
1423
	@@:
1634 IgorA 1424
 
1425
		mov eax,[coord_x]
1426
		mov ebx,[coord_y]
1427
		mov ecx,[w]
2358 IgorA 1428
		;cmp ecx,1
1429
		;jl .coord_end
1430
		cmp ecx,0
1431
		je .coord_end
1432
		jg @f
1433
			add eax,ecx
1434
			inc eax
1435
			neg ecx
1436
		@@:
1634 IgorA 1437
		add ecx,eax
1642 IgorA 1438
		dec ecx
1634 IgorA 1439
		mov edx,[h]
2358 IgorA 1440
		;cmp edx,1
1441
		;jl .coord_end
1442
		cmp edx,0
1443
		je .coord_end
1444
		jg @f
1445
			add ebx,edx
1446
			inc ebx
1447
			neg edx
1448
		@@:
1642 IgorA 1449
 
1634 IgorA 1450
		add edx,ebx
1642 IgorA 1451
		dec edx
1634 IgorA 1452
		mov esi,dword[color]
1453
		stdcall buf_line_h, edi, eax, ebx, ecx, esi ;линия -
1454
		stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;линия |
1455
		stdcall buf_line_h, edi, eax, edx, ecx, esi ;линия -
1456
		stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;линия |
1457
	.coord_end:
1458
popad
1459
	ret
1460
endp
1461
 
1462
align 4
1642 IgorA 1463
proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1464
pushad
1465
	mov edi,[buf_struc]
2358 IgorA 1466
	cmp buf2d_bits,8
1467
	je @f
1642 IgorA 1468
	cmp buf2d_bits,24
2358 IgorA 1469
	je @f
1470
		jmp .coord_end
1471
	@@:
1642 IgorA 1472
		mov eax,[coord_x]
1473
		mov ebx,[coord_y]
1474
		mov edx,[w]
2358 IgorA 1475
		cmp edx,0
1476
		je .coord_end ;если высота 0 пикселей
1477
		jg @f ;если высота положительная
1478
			add eax,edx
1479
			inc eax
1480
			neg edx ;ширину делаем положительной
1481
			;inc edx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1482
		@@:
1642 IgorA 1483
		add edx,eax
2358 IgorA 1484
		dec edx
1642 IgorA 1485
		mov ecx,[h]
2358 IgorA 1486
		cmp ecx,0
1487
		je .coord_end ;если высота 0 пикселей
1488
		jg @f ;если высота положительная
1489
			add ebx,ecx ;сдвигаем верхнюю координату прямоугольника
1490
			inc ebx
1491
			neg ecx ;высоту делаем положительной
1492
			;inc ecx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1493
		@@:
1642 IgorA 1494
		mov esi,dword[color]
1495
		cld
1496
		@@:
1497
			stdcall buf_line_h, edi, eax, ebx, edx, esi ;линия -
1498
			inc ebx
1499
			loop @b
1500
	.coord_end:
1501
popad
1502
	ret
1503
endp
1504
 
1505
align 4
1535 IgorA 1506
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
1507
locals
1508
	po_x dd ?
1509
	po_y dd ?
1510
endl
1511
	pushad
1512
	mov edi,dword[buf_struc]
2358 IgorA 1513
	cmp buf2d_bits,8
1514
	je @f
1535 IgorA 1515
	cmp buf2d_bits,24
2358 IgorA 1516
	je @f
1517
		jmp .error
1518
	@@:
1535 IgorA 1519
		mov edx,dword[color]
1520
 
1521
		finit
1522
		fild dword[coord_x]
1523
		fild dword[coord_y]
1524
		fild dword[r]
1525
		fldz ;px=0
1526
		fld st1 ;py=r
1527
 
1528
		fldpi
1529
		fmul st0,st3
1530
		fistp dword[po_x]
1531
		mov esi,dword[po_x] ;esi=pi*r
1532
		shl esi,1 ;esi=2*pi*r
1533
 
1534
		;st0 = py
1535
		;st1 = px
1536
		;st2 = r
1537
		;st3 = y
1538
		;st4 = x
1539
 
1540
		@@:
1541
			;Point(px + x, y - py)
1542
			fld st1 ;st0=px
1543
			fadd st0,st5 ;st0=px+x
1544
			fistp dword[po_x]
1545
			mov ebx,dword[po_x]
1546
			fld st3 ;st0=y
1547
			fsub st0,st1 ;st0=y-py
1548
			fistp dword[po_y]
1549
			mov ecx,dword[po_y]
1550
			call draw_pixel
1551
			;px += py/r
1552
			fld st0 ;st0=py
1553
			fdiv st0,st3 ;st0=py/r
1554
			faddp st2,st0 ;st3+=st0
1555
			;py -= px/r
1556
			fld st1 ;st0=px
1557
			fdiv st0,st3 ;st0=px/r
1558
			fsubp st1,st0 ;st2-=st0
1559
 
1560
			dec esi
1561
			cmp esi,0
1562
			jge @b
1563
		jmp .exit_fun
1564
	.error:
2358 IgorA 1565
		stdcall print_err,sz_buf2d_circle,txt_err_n8_24b
1535 IgorA 1566
	.exit_fun:
1567
 
1568
	popad
1569
	ret
1570
endp
1571
 
1684 IgorA 1572
;функция для заливки области выбранным цветом
1535 IgorA 1573
align 4
1684 IgorA 1574
proc buf_flood_fill, buf_struc:dword, coord_x:dword, coord_y:dword, mode:dword, color_f:dword, color_b:dword
1575
	pushad
1576
		mov edi,[buf_struc]
1577
		cmp buf2d_bits,24
1578
		jne .end24
1579
 
1580
			mov ebx,dword[coord_x]
1581
			mov ecx,dword[coord_y]
1582
			mov edx,dword[color_f]
1583
			mov esi,dword[color_b]
1584
 
1585
			cmp dword[mode],1 ;в зависимости от 'mode' определяем каким алгоритмом будем пользоваться
1586
			je @f
1587
				call buf_flood_fill_recurs_0 ;заливаем до пикселей цвета esi
1588
				jmp .end24
1589
			@@:
1590
				call buf_flood_fill_recurs_1 ;заливаем пиксели имеющие цвет esi
1591
 
1592
		.end24:
1593
	popad
1594
	ret
1595
endp
1596
 
1597
;input:
1598
; ebx = coord_x
1599
; ecx = coord_y
1600
; edx = цвет заливки
1601
; esi = цвет границы, до которой будет ити заливка
1602
; edi = buf_struc
1603
;output:
1604
; eax = портится
1605
align 4
1606
buf_flood_fill_recurs_0:
1607
	call get_pixel_24
1608
	cmp eax,0xffffffff ;if error coords
1609
	je .end_fun
1610
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1611
	je .end_fun
1612
 
1613
		call draw_pixel
1614
 
1615
		dec ebx
1616
		call get_pixel_24
1617
		cmp eax,esi
1618
		je @f
1619
			call buf_flood_fill_recurs_0
1620
		@@:
1621
		inc ebx
1622
 
1623
 
1624
		inc ebx
1625
		call get_pixel_24
1626
		cmp eax,esi
1627
		je @f
1628
			call buf_flood_fill_recurs_0
1629
		@@:
1630
		dec ebx
1631
 
1632
		dec ecx
1633
		call get_pixel_24
1634
		cmp eax,esi
1635
		je @f
1636
			call buf_flood_fill_recurs_0
1637
		@@:
1638
		inc ecx
1639
 
1640
		inc ecx
1641
		call get_pixel_24
1642
		cmp eax,esi
1643
		je @f
1644
			call buf_flood_fill_recurs_0
1645
		@@:
1646
		dec ecx
1647
 
1648
	.end_fun:
1649
	ret
1650
 
1651
;input:
1652
; ebx = coord_x
1653
; ecx = coord_y
1654
; edx = цвет заливки
1655
; esi = цвет пикселей, по которым будет ити заливка
1656
; edi = buf_struc
1657
;output:
1658
; eax = портится
1659
align 4
1660
buf_flood_fill_recurs_1:
1661
	call get_pixel_24
1662
	cmp eax,0xffffffff ;if error coords
1663
	je .end_fun
1664
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1665
	je .end_fun
1666
	cmp eax,esi ;если цвет пикселя не совпал с заливаемым цветом заливки, то прекращаем заливку
1667
	jne .end_fun
1668
 
1669
		call draw_pixel
1670
 
1671
		dec ebx
1672
		call get_pixel_24
1673
		cmp eax,esi
1674
		jne @f
1675
			call buf_flood_fill_recurs_1
1676
		@@:
1677
		inc ebx
1678
 
1679
 
1680
		inc ebx
1681
		call get_pixel_24
1682
		cmp eax,esi
1683
		jne @f
1684
			call buf_flood_fill_recurs_1
1685
		@@:
1686
		dec ebx
1687
 
1688
		dec ecx
1689
		call get_pixel_24
1690
		cmp eax,esi
1691
		jne @f
1692
			call buf_flood_fill_recurs_1
1693
		@@:
1694
		inc ecx
1695
 
1696
		inc ecx
1697
		call get_pixel_24
1698
		cmp eax,esi
1699
		jne @f
1700
			call buf_flood_fill_recurs_1
1701
		@@:
1702
		dec ecx
1703
 
1704
	.end_fun:
1705
	ret
1706
 
1910 IgorA 1707
;функция для рисования точки
1684 IgorA 1708
align 4
2658 IgorA 1709
proc buf_set_pixel uses ebx ecx edx edi, buf_struc:dword, coord_x:dword, coord_y:dword, color:dword
1710
	mov edi,dword[buf_struc]
1711
	mov ebx,dword[coord_x]
1712
	mov ecx,dword[coord_y]
1713
	mov edx,dword[color]
1714
	call draw_pixel
1910 IgorA 1715
	ret
1716
endp
1717
 
2658 IgorA 1718
;output:
1719
; eax = цвет точки
1720
; в случае ошибки eax = 0xffffffff
1910 IgorA 1721
align 4
2658 IgorA 1722
proc buf_get_pixel uses ebx ecx edi, buf_struc:dword, coord_x:dword, coord_y:dword
1723
	mov edi,dword[buf_struc]
1724
	mov ebx,[coord_x]
1725
	mov ecx,[coord_y]
1726
 
1727
	cmp buf2d_bits,8
1728
	jne @f
1729
		call get_pixel_8
1730
		jmp .end_fun
1731
	@@:
1732
	cmp buf2d_bits,24
1733
	jne @f
1734
		call get_pixel_24
1735
		jmp .end_fun
1736
	@@:
1737
	cmp buf2d_bits,32
1738
	jne @f
1739
		call get_pixel_32
1740
		;jmp .end_fun
1741
	@@:
1742
	.end_fun:
1743
	ret
1744
endp
1745
 
1746
align 4
1535 IgorA 1747
proc buf_img_wdiv2, buf_struc:dword
1748
	pushad
1749
	mov edi,dword[buf_struc]
1750
	cmp buf2d_bits,24
1751
	jne .end_draw_24
1752
		mov eax,buf2d_w
1753
		mov ecx,buf2d_h
1754
		imul ecx,eax
1755
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
1756
	.end_draw_24:
1757
	popad
1758
	ret
1759
endp
1760
 
1761
;input:
1762
;data_rgb - pointer to rgb data
1763
;size - count img pixels (size img data / 3(rgb) )
1764
align 4
1765
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
1766
  ;push eax ebx ecx edx
1767
  mov eax,dword[data_rgb]
1768
  mov ecx,dword[size] ;ecx = size
1769
  lea ecx,[ecx+ecx*2]
1770
  cld
1771
  @@: ;затемнение цвета пикселей
1538 IgorA 1772
		shr byte[eax],1
1773
		inc eax
1774
		loop @b
1535 IgorA 1775
 
1776
  mov eax,dword[data_rgb]
1777
  mov ecx,dword[size] ;ecx = size
1778
  shr ecx,1
1779
  @@: ;сложение цветов пикселей
1538 IgorA 1780
		mov bx,word[eax+3] ;копируем цвет соседнего пикселя
1781
		add word[eax],bx
1782
		mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
1783
		add byte[eax+2],bl
1784
		add eax,6 ;=2*3
1785
		loop @b
1535 IgorA 1786
 
1787
  mov eax,dword[data_rgb]
1788
  add eax,3
1789
  mov ebx,eax
1790
  add ebx,3
1791
  mov ecx,dword[size] ;ecx = size
1792
  shr ecx,1
1793
  dec ecx ;лишний пиксель
1794
  @@: ;поджатие пикселей
1538 IgorA 1795
		mov edx,dword[ebx]
1796
		mov word[eax],dx
1797
		shr edx,16
1798
		mov byte[eax+2],dl
1535 IgorA 1799
 
1538 IgorA 1800
		add eax,3
1801
		add ebx,6
1802
		loop @b
1535 IgorA 1803
  ;pop edx ecx ebx eax
1804
  ret
1805
endp
1806
 
1807
align 4
1808
proc buf_img_hdiv2, buf_struc:dword
1809
	pushad
1810
	mov edi,dword[buf_struc]
1811
	cmp buf2d_bits,24
1812
	jne .end_draw_24
1813
		mov eax,buf2d_w
1814
		mov ecx,buf2d_h
1815
		imul ecx,eax
1816
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
1817
	.end_draw_24:
1818
	popad
1819
	ret
1820
endp
1821
 
1822
;input:
1823
;data_rgb - pointer to rgb data
1824
;size - count img pixels (size img data / 3(rgb) )
1825
;size_w - width img in pixels
1826
align 4
1827
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
1828
  ;pushad
1829
 
1830
  mov eax,dword[data_rgb] ;eax =
1831
  mov ecx,dword[size]	  ;ecx = size
1832
  lea ecx,[ecx+ecx*2]
1833
  cld
1834
  @@: ;затемнение цвета пикселей
1835
    shr byte[eax],1
1836
    inc eax
1837
    loop @b
1838
 
1839
  mov eax,dword[data_rgb] ;eax =
1840
  mov edi,dword[size_w]
1841
  lea esi,[edi+edi*2] ;esi = width*3(rgb)
1842
  mov ebx,esi
1843
  add ebx,eax
1844
  mov ecx,dword[size]  ;ecx = size
1845
  shr ecx,1
1846
  xor edi,edi
1847
  @@: ;сложение цветов пикселей
1848
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
1849
    add word[eax],dx
1850
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
1851
    add byte[eax+2],dl
1852
 
1853
    add eax,3
1854
    add ebx,3
1855
    inc edi
1856
    cmp edi,dword[size_w]
1857
    jl .old_line
1858
      add eax,esi
1859
      add ebx,esi
1860
      xor edi,edi
1861
    .old_line:
1862
    loop @b
1863
 
1864
 
1865
  mov eax,dword[data_rgb] ;eax =
1866
  add eax,esi ;esi = width*3(rgb)
1867
  mov ebx,esi
1868
  add ebx,eax
1869
  mov ecx,dword[size] ;ecx = size
1870
  shr ecx,1
1871
  sub ecx,dword[size_w] ;лишняя строка пикселей
1872
  xor edi,edi
1873
  @@: ;поджатие пикселей
1874
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
1875
    mov word[eax],dx
1876
    shr edx,16
1877
    mov byte[eax+2],dl
1878
 
1879
    add eax,3
1880
    add ebx,3
1881
    inc edi
1882
    cmp edi,dword[size_w]
1883
    jl .old_line_2
1884
      add ebx,esi
1885
      xor edi,edi
1886
    .old_line_2:
1887
    loop @b
1888
 
1889
  ;popad
1890
  ret
1891
endp
1892
 
1893
;преобразование буфера из 24-битного в 8-битный
1894
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
1895
align 4
1896
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
1897
	pushad
1898
	mov edi,dword[buf_struc]
1899
	cmp buf2d_bits,24
1900
	jne .error
1901
		mov eax,buf2d_w
1902
		mov ecx,buf2d_h
1903
		imul ecx,eax
1904
		mov esi,ecx
1905
		;ebx - память из которой копируется
1906
		;edx - память куда копируется
1907
		mov edx,buf2d_data
1908
		mov ebx,edx
1909
		cmp [spectr],3
1910
		jge @f
1911
			add ebx,[spectr]
1912
		@@:
1913
			mov al,byte[ebx]
1914
			mov byte[edx],al
1915
			add ebx,3
1916
			inc edx
1917
			loop @b
1918
		mov buf2d_bits,8
1919
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
1920
		jmp .end_conv
1921
	.error:
1922
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
1923
	.end_conv:
1924
	popad
1925
	ret
1926
endp
1927
 
1928
;преобразование буфера из 24-битного в 32-битный
1929
align 4
1930
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
1931
	pushad
1932
	mov edi,dword[buf_struc]
1933
	cmp buf2d_bits,24
1934
	jne .error1
1935
		mov ecx,buf2d_w
1936
		mov ebx,buf2d_h
1937
		imul ebx,ecx
1938
		mov ecx,ebx ;ecx = size  8 b
1939
		shl ebx,2   ;ebx = size 32 b
1940
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
1941
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1942
		mov buf2d_bits,32
1943
		mov edx,ebx ;edx = size 32 b
1944
		sub ebx,ecx ;ebx = size 24 b
1945
		mov eax,ecx
1946
		;eax - размер  8 битных данных
1947
		;ebx - размер 24 битных данных
1948
		;edx - размер 32 битных данных
1949
		add ebx,buf2d_data
1950
		add edx,buf2d_data
1951
		mov edi,dword[buf_str8]
1952
		cmp buf2d_bits,8
1953
		jne .error2
1954
		add eax,buf2d_data
1955
		mov edi,edx
1956
		;eax - указатель на конец  8 битных данных
1957
		;ebx - указатель на конец 24 битных данных
1958
		;edi - указатель на конец 32 битных данных
1959
		@@:
1960
			sub edi,4 ;отнимаем в начале цикла,
1961
			sub ebx,3 ; потому, что указатели стоят
1962
			dec eax   ; за пределами буферов
1963
			mov edx,dword[ebx]
1964
			mov dword[edi],edx
1965
			mov dl,byte[eax]
1966
			mov byte[edi+3],dl
1967
			loop @b
1968
 
1969
		jmp .end_conv
1970
	.error1:
1971
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
1972
		jmp .end_conv
1973
	.error2:
1974
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
1975
	.end_conv:
1976
	popad
1977
	ret
1978
endp
1979
 
1980
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
1981
; указываются координаты вставки буфера buf_source относительно buf_destination
1982
; прозрачность при копировании не учитывается
1983
align 4
1984
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
1985
	locals
1986
		right_bytes dd ?
1987
	endl
1988
	pushad
1989
 
1990
	mov edi,[buf_source]
1991
	cmp buf2d_bits,24
1992
	je .sou24
1993
	cmp buf2d_bits,32
1994
	je .sou32
1995
		jmp .copy_end ;формат буфера не поодерживается
1996
 
1648 IgorA 1997
	.sou24: ;в источнике 24 битная картинка
1535 IgorA 1998
	mov eax,buf2d_w
1999
	mov edx,buf2d_h ;высота копируемой картинки
2000
	mov esi,buf2d_data ;данные копируемой картинки
2001
 
2002
	mov edi,[buf_destination]
2003
	cmp buf2d_bits,24
2004
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2005
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2006
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2007
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2008
		mov ebx,buf2d_h ;ebx - высота основного буфера
2009
		mov ecx,[coord_y]
2422 IgorA 2010
		cmp ecx,0
2011
		jge @f
2012
			;если координата coord_y<0 (1-я настройка)
2013
			add edx,ecx ;уменьшаем высоту копируемой картинки
2014
			cmp edx,0
2015
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2016
			neg ecx
2017
			;inc ecx
2018
			imul ecx,eax
2019
			lea ecx,[ecx+ecx*2] ;по 3 байта на пиксель
2020
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2021
			xor ecx,ecx ;обнуляем координату coord_y
2022
		@@:
1535 IgorA 2023
		cmp ecx,ebx
2024
		jge .copy_end ;если координата 'y' больше высоты буфера
2025
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2026
		cmp ecx,ebx
2027
		jle @f
2028
			sub ecx,ebx
2029
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2030
		@@:
2031
		mov ebx,buf2d_w
2422 IgorA 2032
		mov ecx,[coord_y] ;ecx используем для временных целей
2033
		cmp ecx,0
2034
		jg .end_otr_c_y_24
2035
			;если координата coord_y<=0 (2-я настройка)
2036
			mov ecx,[coord_x]
2037
			jmp @f
2038
		.end_otr_c_y_24:
2039
		imul ecx,ebx
1535 IgorA 2040
		add ecx,[coord_x]
2422 IgorA 2041
		@@:
1535 IgorA 2042
		lea ecx,[ecx+ecx*2]
2043
		add ecx,buf2d_data
2044
		sub ebx,eax
2045
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2046
 
2047
	mov [right_bytes],0
2048
	mov ecx,[coord_x]
2049
	cmp ecx,ebx
2050
	jl @f
2051
		sub ecx,ebx
2052
		sub eax,ecx ;укорачиваем копируемую строку
2053
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2054
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2055
		mov [right_bytes],ecx
2056
	@@:
2057
 
2058
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
2059
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2060
 
2061
	cld
2062
	cmp [right_bytes],0
2063
	jg .copy_1
2064
	.copy_0: ;простое копирование
2065
		mov ecx,eax
2066
		rep movsb
2067
		add edi,ebx
2068
		dec edx
2069
		cmp edx,0
2070
		jg .copy_0
2071
	jmp .copy_end
2072
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2073
		mov ecx,eax
2074
		rep movsb
2075
		add edi,ebx
2076
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2077
		dec edx
2078
		cmp edx,0
2079
		jg .copy_1
2080
	jmp .copy_end
2081
 
2082
	.sou32: ;в источнике 32 битная картинка
2083
	mov eax,buf2d_w
2084
	mov edx,buf2d_h ;высота копируемой картинки
2085
	mov esi,buf2d_data ;данные копируемой картинки
2086
 
2087
	mov edi,[buf_destination]
2088
	cmp buf2d_bits,24
2089
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2090
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2091
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2092
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2093
		mov ebx,buf2d_h ;ebx - высота основного буфера
2094
		mov ecx,[coord_y]
2422 IgorA 2095
		cmp ecx,0
2096
		jge @f
2097
			;если координата coord_y<0 (1-я настройка)
2098
			add edx,ecx ;уменьшаем высоту копируемой картинки
2099
			cmp edx,0
2100
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2101
			neg ecx
2102
			;inc ecx
2103
			imul ecx,eax
2104
			shl ecx,2 ;по 4 байта на пиксель
2105
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2106
			xor ecx,ecx ;обнуляем координату coord_y
2107
		@@:
1535 IgorA 2108
		cmp ecx,ebx
2109
		jge .copy_end ;если координата 'y' больше высоты буфера
2110
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2111
		cmp ecx,ebx
2112
		jle @f
2113
			sub ecx,ebx
2114
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2115
		@@:
2116
		mov ebx,buf2d_w
2422 IgorA 2117
		;mov ecx,ebx ;ecx используем для временных целей
2118
		;imul ecx,[coord_y]
2119
		;add ecx,[coord_x]
2120
		mov ecx,[coord_y] ;ecx используем для временных целей
2121
		cmp ecx,0
2122
		jg .end_otr_c_y_32
2123
			;если координата coord_y<=0 (2-я настройка)
2124
			mov ecx,[coord_x]
2125
			jmp @f
2126
		.end_otr_c_y_32:
2127
		imul ecx,ebx
1535 IgorA 2128
		add ecx,[coord_x]
2422 IgorA 2129
		@@:
1535 IgorA 2130
		lea ecx,[ecx+ecx*2]
2131
		add ecx,buf2d_data
2132
		sub ebx,eax
2133
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2134
 
2135
	mov [right_bytes],0
2136
	mov ecx,[coord_x]
2137
	cmp ecx,ebx
2138
	jl @f
2139
		sub ecx,ebx
2140
		sub eax,ecx ;укорачиваем копируемую строку
2141
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2142
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2143
		mov [right_bytes],ecx
2144
	@@:
2145
 
2146
	;eax - колличество пикселей в 1-й строке копируемой картинки
2147
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2148
 
2149
	cld
2150
	cmp [right_bytes],0
2151
	jg .copy_3
2152
	.copy_2: ;простое копирование
2153
		mov ecx,eax
2154
		@@:
2155
			movsw
2156
			movsb
2157
			inc esi
2158
			loop @b
2159
		add edi,ebx
2160
		dec edx
2161
		cmp edx,0
2162
		jg .copy_2
2163
	jmp .copy_end
2164
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
2165
		mov ecx,eax
2166
		@@:
2167
			movsw
2168
			movsb
2169
			inc esi
2170
			loop @b
2171
		add edi,ebx
2172
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2173
		dec edx
2174
		cmp edx,0
2175
		jg .copy_3
2176
 
2177
	.copy_end:
2178
	popad
2179
	ret
2180
endp
2181
 
2182
;input:
2183
; esi = pointer to color1 + transparent
2184
; edi = pointer to background color2
2185
;output:
2186
; [edi] = combine color
2187
align 4
2188
combine_colors:
2189
	push ax bx cx dx
2190
	mov bx,0x00ff ;---get transparent---
2748 IgorA 2191
	movzx cx,byte[esi+3] ;pro
1535 IgorA 2192
	sub bx,cx ;256-pro
1653 IgorA 2193
	;---blye---
2748 IgorA 2194
	movzx ax,byte[esi]
1535 IgorA 2195
	imul ax,bx
2748 IgorA 2196
	movzx dx,byte[edi]
1535 IgorA 2197
	imul dx,cx
2198
	add ax,dx
1653 IgorA 2199
	mov byte[edi],ah
1535 IgorA 2200
	;---green---
2748 IgorA 2201
	movzx ax,byte[esi+1]
1535 IgorA 2202
	imul ax,bx
2748 IgorA 2203
	movzx dx,byte[edi+1]
1535 IgorA 2204
	imul dx,cx
2205
	add ax,dx
2206
	mov byte[edi+1],ah
1653 IgorA 2207
	;---red---
2748 IgorA 2208
	movzx ax,byte[esi+2]
1535 IgorA 2209
	imul ax,bx
2748 IgorA 2210
	movzx dx,byte[edi+2]
1535 IgorA 2211
	imul dx,cx
2212
	add ax,dx
1653 IgorA 2213
	mov byte[edi+2],ah
1535 IgorA 2214
 
2215
	pop dx cx bx ax
2216
	ret
2217
 
2218
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
2219
; указываются координаты вставки буфера buf_source относительно buf_destination
2220
; при копировании учитывается прозрачность
2221
align 4
2222
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2223
	locals
2224
		right_bytes dd ?
2225
	endl
2226
	pushad
2227
 
2228
	mov edi,[buf_source]
2229
	cmp buf2d_bits,32
2230
	jne .copy_end ;формат буфера не поодерживается
2231
	mov eax,buf2d_w
2232
	mov edx,buf2d_h ;высота копируемой картинки
2233
	mov esi,buf2d_data ;данные копируемой картинки
2234
 
2235
	mov edi,[buf_destination]
2236
	cmp buf2d_bits,24
2237
	jne .copy_end ;формат буфера не поодерживается
2238
		mov ebx,buf2d_h ;ebx - высота основного буфера
2239
		mov ecx,[coord_y]
2383 IgorA 2240
		cmp ecx,0
2241
		jge @f
2242
			;если координата coord_y<0 (1-я настройка)
2243
			add edx,ecx ;уменьшаем высоту копируемой картинки
2244
			cmp edx,0
2245
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2246
			neg ecx
2247
			;inc ecx
2248
			imul ecx,eax
2422 IgorA 2249
			shl ecx,2 ;по 4 байта на пиксель
2383 IgorA 2250
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2251
			xor ecx,ecx ;обнуляем координату coord_y
2252
		@@:
1535 IgorA 2253
		cmp ecx,ebx
2254
		jge .copy_end ;если координата 'y' больше высоты буфера
2255
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2256
		cmp ecx,ebx
2257
		jle @f
2258
			sub ecx,ebx
2259
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2260
		@@:
2261
		mov ebx,buf2d_w
2262
		mov ecx,ebx ;ecx используем для временных целей
2383 IgorA 2263
		cmp [coord_y],0
2264
		jg .end_otr_c_y
2265
			;если координата coord_y<=0 (2-я настройка)
2266
			mov ecx,[coord_x]
2267
			jmp @f
2268
		.end_otr_c_y:
1535 IgorA 2269
		imul ecx,[coord_y]
2270
		add ecx,[coord_x]
2383 IgorA 2271
		@@:
1535 IgorA 2272
		lea ecx,[ecx+ecx*2]
2273
		add ecx,buf2d_data
2274
		sub ebx,eax
2275
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2276
 
2277
	mov [right_bytes],0
2278
	mov ecx,[coord_x]
2279
	cmp ecx,ebx
2280
	jl @f
2281
		sub ecx,ebx
2282
		sub eax,ecx ;укорачиваем копируемую строку
2283
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2284
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2285
		mov [right_bytes],ecx
2286
	@@:
2287
 
2288
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2658 IgorA 2289
 
1535 IgorA 2290
	cld
2291
	cmp [right_bytes],0
2292
	jg .copy_1
2293
	.copy_0: ;простое копирование
2294
		mov ecx,eax
2295
		@@:
2296
			call combine_colors
2297
			add edi,3
2298
			add esi,4
2299
			loop @b
2300
		add edi,ebx
2301
		dec edx
2302
		cmp edx,0
2303
		jg .copy_0
2304
	jmp .copy_end
2305
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2306
		mov ecx,eax
2307
		@@:
2308
			call combine_colors
2309
			add edi,3
2310
			add esi,4
2311
			loop @b
2312
		add edi,ebx
2313
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2314
		dec edx
2315
		cmp edx,0
2316
		jg .copy_1
2317
 
2318
	.copy_end:
2319
	popad
2320
	ret
2321
endp
2322
 
2323
;input:
2324
; ebx - color1
2325
; esi = pointer to transparent
2326
; edi = pointer to background color2
2327
;output:
2328
; [edi] = combine color
2329
align 4
2330
combine_colors_2:
2331
	push ax ebx cx dx si
2332
	mov cl,byte[esi] ;pro
2333
	xor ch,ch
2334
	mov si,0x00ff ;---get transparent---
2335
	sub si,cx ;256-pro
2336
 
1653 IgorA 2337
		;---blye---
2748 IgorA 2338
		movzx ax,bl
1535 IgorA 2339
		shr ebx,8
2340
		imul ax,si
2748 IgorA 2341
		movzx dx,byte[edi]
1535 IgorA 2342
		imul dx,cx
2343
		add ax,dx
1653 IgorA 2344
		mov byte[edi],ah
1535 IgorA 2345
		;---green---
2748 IgorA 2346
		movzx ax,bl
1535 IgorA 2347
		shr ebx,8
2348
		imul ax,si
2748 IgorA 2349
		movzx dx,byte[edi+1]
1535 IgorA 2350
		imul dx,cx
2351
		add ax,dx
2352
		mov byte[edi+1],ah
2353
		;---red---
2748 IgorA 2354
		movzx ax,bl
1535 IgorA 2355
		imul ax,si
2748 IgorA 2356
		movzx dx,byte[edi+2]
1535 IgorA 2357
		imul dx,cx
2358
		add ax,dx
1653 IgorA 2359
		mov byte[edi+2],ah
1535 IgorA 2360
 
2361
	pop si dx cx ebx ax
2362
	ret
2363
 
2364
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
2365
; указываются координаты вставки буфера buf_source относительно buf_destination
2366
align 4
2367
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
2368
	locals
2383 IgorA 2369
		lost_bytes dd ? ;число потерянных байтов в строке копируемого изображеня (тех что не влазят в буфер)
1535 IgorA 2370
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
2371
	endl
2372
	pushad
2373
 
2374
	mov edi,[buf_source]
2375
	cmp buf2d_bits,8
2376
	jne .error1 ;формат буфера не поодерживается
2383 IgorA 2377
	mov eax,buf2d_w ;ширина копируемой картинки
1535 IgorA 2378
	mov edx,buf2d_h ;высота копируемой картинки
2379
	mov esi,buf2d_data ;данные копируемой картинки
2380
 
2381
	mov edi,[buf_destination]
2382
	cmp buf2d_bits,24
2383
	jne .error2 ;формат буфера не поодерживается
1642 IgorA 2384
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2385
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2386
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2387
		mov ebx,buf2d_h ;ebx - высота основного буфера
2388
		mov ecx,[coord_y]
2367 IgorA 2389
		cmp ecx,0
2390
		jge @f
2391
			;если координата coord_y<0 (1-я настройка)
2392
			add edx,ecx ;уменьшаем высоту копируемой картинки
2383 IgorA 2393
			cmp edx,0
2394
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2367 IgorA 2395
			neg ecx
2396
			;inc ecx
2397
			imul ecx,eax
2398
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2399
			xor ecx,ecx ;обнуляем координату coord_y
2400
		@@:
1535 IgorA 2401
		cmp ecx,ebx
2402
		jge .copy_end ;если координата 'y' больше высоты буфера
2403
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2404
		cmp ecx,ebx
2405
		jle @f
2406
			sub ecx,ebx
2407
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2408
		@@:
2409
		mov ebx,buf2d_w
2367 IgorA 2410
		mov ecx,[coord_y] ;ecx используем для временных целей
2411
		cmp ecx,0
2383 IgorA 2412
		jg .end_otr_c_y
2413
			;если координата coord_y<=0 (2-я настройка)
2367 IgorA 2414
			mov ecx,[coord_x]
2415
			jmp @f
2416
		.end_otr_c_y:
2417
		imul ecx,ebx
1535 IgorA 2418
		add ecx,[coord_x]
2367 IgorA 2419
		@@:
1535 IgorA 2420
		lea ecx,[ecx+ecx*2]
2383 IgorA 2421
		add ecx,buf2d_data ;buf2d_data данные основного буфера
2422
		sub ebx,eax ;ebx - ширина основного буфера минус ширина рисуемого буфера
1535 IgorA 2423
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2424
 
2383 IgorA 2425
	mov dword[lost_bytes],0
1535 IgorA 2426
	mov ecx,[coord_x]
2383 IgorA 2427
	cmp ecx,0
2428
	jge @f
2429
		neg ecx
2430
		;inc ecx
2431
		cmp eax,ecx ;eax - ширина копируемой картинки
2432
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2433
		add [lost_bytes],ecx
2434
		sub eax,ecx ;укорачиваем копируемую строку
2435
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2436
		add esi,ecx
2437
		lea ecx,[ecx+ecx*2]
2438
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2439
		xor ecx,ecx
2440
	@@:
1535 IgorA 2441
	cmp ecx,ebx
2383 IgorA 2442
	jle @f
1535 IgorA 2443
		sub ecx,ebx
2444
		sub eax,ecx ;укорачиваем копируемую строку
2445
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2446
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2383 IgorA 2447
		add [lost_bytes],ecx
1535 IgorA 2448
	@@:
2449
 
2450
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2451
	mov [dest_w_bytes],ebx
2452
	mov ebx,[color]
2453
 
2454
	cld
2383 IgorA 2455
	cmp dword[lost_bytes],0
1535 IgorA 2456
	jg .copy_1
2457
	.copy_0: ;простое копирование
2458
		mov ecx,eax
2459
		@@:
2460
			call combine_colors_2
2461
			add edi,3
2462
			inc esi
2463
			loop @b
2464
		add edi,[dest_w_bytes]
2465
		dec edx
2466
		cmp edx,0
2467
		jg .copy_0
2468
	jmp .copy_end
2383 IgorA 2469
	.copy_1: ;не простое копирование (картинка вылазит за левую и/или правую сторону)
1535 IgorA 2470
		mov ecx,eax
2471
		@@:
2472
			call combine_colors_2
2473
			add edi,3
2474
			inc esi
2475
			loop @b
2476
		add edi,[dest_w_bytes]
2383 IgorA 2477
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 2478
		dec edx
2479
		cmp edx,0
2480
		jg .copy_1
2481
 
2482
	jmp .copy_end
2483
	.error1:
2484
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
2485
		jmp .copy_end
2486
	.error2:
2487
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
2488
	.copy_end:
2489
	popad
2490
	ret
2491
endp
2492
 
2493
;преобразование 8-битного буфера размером 16*16 в размер 1*256 символов
2494
align 4
2495
proc buf_convert_text_matrix, buf_struc:dword
2496
	locals
2497
		tmp_mem dd ?
2498
		c1 dw ?
2499
		c2 dd ?
2500
		c3 dw ?
2501
	endl
2502
	pushad
2503
	mov edi,dword[buf_struc]
2504
	cmp buf2d_bits,8
2505
	jne .error
2506
		mov ecx,buf2d_h
2507
		mov ebx,ecx
2508
		shr ebx,4 ;предполагаем что в буфере 16 строк с символами, потому делим на 2^4
2509
		mov edx,buf2d_w
2510
		imul ecx,edx ;ecx = size  8 b
2511
		invoke mem.alloc,ecx ;выделяем временную память
2512
		mov [tmp_mem],eax ;eax - new memory
2513
 
2514
		shr edx,4 ;предполагаем что в буфере 16 колонок с символами, потому делим на 2^4
2515
		mov eax,ebx
2516
		imul ebx,edx ;вычисляем кооличество пикселей на 1 символ
2517
		;eax = bhe - высота буквы
2518
		;ebx = bwi*bhe - колличество пикселей в 1-й букве
2519
		;edx = bwi - ширина буквы
2520
		;ecx,esi,edi - используются в цикле .c_0
2521
		shr buf2d_w,4
2522
		shl buf2d_h,4 ;преобразовываем размеры буфера
2523
 
2524
		cld
2525
		mov esi,buf2d_data
2526
		mov edi,[tmp_mem]
2527
		mov word[c3],16
2528
		.c_3:
2529
			mov dword[c2],eax
2530
			.c_2:
2531
				mov word[c1],16
2532
				.c_1:
2533
					mov ecx,edx ;.c_0:
2534
					rep movsb
2535
					add edi,ebx
2536
					sub edi,edx ;edi+=(bwi*bhe-bwi)
2537
					dec word[c1]
2538
					cmp word[c1],0
2539
					jg .c_1
2540
				add edi,edx
2541
				shl ebx,4
2542
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
2543
				shr ebx,4
2544
				dec dword[c2]
2545
				cmp dword[c2],0
2546
				jg .c_2
2547
			sub edi,ebx
2548
			shl ebx,4
2549
			add edi,ebx ;edi+=(15*bwi*bhe)
2550
			shr ebx,4
2551
			dec word[c3]
2552
			cmp word[c3],0
2553
			jg .c_3
2554
 
2555
		mov edi,dword[buf_struc] ;копирование новой матрицы в основной буфер
2556
		mov edi,buf2d_data
2557
		mov esi,[tmp_mem]
2558
		mov ecx,ebx
2559
		shl ecx,8
2560
		rep movsb
2561
		invoke mem.free,[tmp_mem] ;чистим временную память
2562
		jmp .end_conv
2563
	.error:
2564
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
2565
	.end_conv:
2566
	popad
2567
	ret
2568
endp
2569
 
2570
align 4
2571
buf_s_matr buf_2d_header ? ;локальная матрица символа
2572
 
2573
align 4
2574
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
2575
	locals
2576
		buf_t_matr_offs dd ?
2577
	endl
2578
	pushad
2579
	mov edi,dword[buf_struc]
2580
	cmp buf2d_bits,24
2581
	jne .error2
2582
	mov edi,dword[buf_t_matr]
2583
	cmp buf2d_bits,8
2584
	jne .error1
2585
		mov edx,buf2d_data
2586
		mov [buf_t_matr_offs],edx
2587
		mov ecx,BUF_STRUCT_SIZE ;копируем структуру текстовой матрицы
2588
		mov esi,edi
2589
		lea edi,[buf_s_matr]
2590
		cld
2591
		rep movsb
2592
		lea edi,[buf_s_matr]
2593
		shr buf2d_h,8 ;делим высоту символьного буфера на 256, для нахождения высоты 1-го символа
2594
		mov ebx,buf2d_h ;берем высоту символа
2595
		mov ecx,buf2d_w ;берем ширину символа
2596
 
2597
		mov eax,[coord_x]
2598
		mov esi,[text]
2599
		cmp byte[esi],0
2600
		je .end_draw ;если пустая строка
2601
		@@:
2602
			xor edx,edx
2603
			mov dl,byte[esi] ;берем код символа
2604
			imul edx,ebx ;умножаем его на высоту символа
2605
			imul edx,ecx ;умножаем на ширину символа
2606
			add edx,[buf_t_matr_offs] ;прибавляем смещение 0-го символа, т. е. получается смещение выводимого символа
2607
			mov buf2d_data,edx ;в локальный буфер символа, ставим указатель на нужный символ из буфера buf_t_matr
2608
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
2609
			add eax,ecx
2610
			.new_s:
2611
				inc esi
2612
				cmp byte[esi],13
2613
				jne .no_13
2614
					mov eax,[coord_x]
2615
					add [coord_y],ebx
2616
					jmp .new_s
2617
				.no_13:
2618
			cmp byte[esi],0
2619
			jne @b
2620
		jmp .end_draw
2621
	.error1:
2622
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
2623
		jmp .end_draw
2624
	.error2:
2625
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
2626
	.end_draw:
2627
	popad
2628
	ret
2629
endp
2630
 
2631
align 4
2632
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
2633
	pushad
2634
	mov eax,63
2635
	mov ebx,1
2636
 
2637
	mov esi,[fun]
2638
	@@:
2639
		mov cl,byte[esi]
2640
		int 0x40
2641
		inc esi
2642
		cmp byte[esi],0
2643
		jne @b
2644
	mov cl,':'
2645
	int 0x40
2646
	mov cl,' '
2647
	int 0x40
2648
	mov esi,[mes]
2649
	@@:
2650
		mov cl,byte[esi]
2651
		int 0x40
2652
		inc esi
2653
		cmp byte[esi],0
2654
		jne @b
2655
	popad
2656
	ret
2657
endp
2658
 
2659
;input:
2660
; ebp+8  = p0
2661
; ebp+12 = p1
2662
align 4
2663
line_len4i:
2664
	push ebp
2665
	mov ebp,esp
2666
		finit
2667
		fild word [ebp+8]
2668
		fisub word [ebp+12]
2669
		fmul st0,st0 ;st0=x^2
2670
		fild word [ebp+10]
2671
		fisub word [ebp+14]
2672
		fmul st0,st0 ;st0=y^2
2673
		fadd st0,st1
2674
		fsqrt
2675
		fstp dword [ebp+12]
2676
	pop ebp
2677
	ret 4 ;8
2678
 
2679
align 4
1727 IgorA 2680
proc buf_curve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
1535 IgorA 2681
	locals
2682
		delt_t dd ?
2683
		opr_param dd ?
2684
		v_poi_0 dd ?
2685
	endl
2686
	pushad
2687
 
2688
;float t, xt,yt;
2689
;for(t=.0;t<1.;t+=.005){
2690
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
2691
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
2692
;  dc.SetPixel(xt,yt,255L);
2693
;}
2694
 
1727 IgorA 2695
	mov edx,[color] ;set curve color
1535 IgorA 2696
	mov edi,[buffer]
2697
	xor ebx,ebx
2698
	xor ecx,ecx
2699
 
2700
	finit
2701
 
2702
	; calculate delta t
2703
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
2704
	fadd dword[esp]
2705
	add esp,4 ;pop ...
2706
 
2707
	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
2708
	fadd dword[esp]
2709
	add esp,4 ;pop ...
2710
 
2711
	fadd st0,st0 ; len*=2
2712
	ftst
2713
	fstsw ax
2714
 
2715
	fld1
2716
	sahf
2717
	jle @f ;избегаем деления на 0
2718
		fdiv st0,st1
2719
	@@:
2720
	fstp dword[delt_t]
2721
 
2722
	finit
2723
 
2724
	;fild word[coord_p2+2] ;y2
2725
	fild word[coord_p1+2] ;y1
2726
	fild word[coord_p0+2] ;y0
2727
	fild word[coord_p2] ;x2
2728
	fild word[coord_p1] ;x1
2729
	fild word[coord_p0] ;x0
2730
	fld dword[delt_t]
2731
	fldz ;t=.0
2732
 
2733
	@@:
2734
		fld1
2735
		fsub st0,st1 ;1.-t
2736
		fmul st0,st0 ;pow(1.-t,2)
2737
		fmul st0,st3 ;...*x0
2738
		fstp dword[opr_param]
2739
 
2740
		fld1
2741
		fsub st0,st1 ;1.-t
2742
		fmul st0,st1 ;(1.-t)*t
2743
		fadd st0,st0
2744
		fmul st0,st4 ;...*x1
2745
		mov esi,dword[opr_param]
2746
		fstp dword[opr_param]
2747
 
2748
		fldz
2749
		fadd st0,st1 ;0+t
2750
		fmul st0,st0 ;t*t
2751
		fmul st0,st5 ;...*x2
2752
 
2753
		fadd dword[opr_param]
2754
		mov dword[opr_param],esi
2755
		fadd dword[opr_param]
2756
		fistp word[v_poi_0] ;x
2757
 
2758
		fld1
2759
		fsub st0,st1 ;1.-t
2760
		fmul st0,st0 ;pow(1.-t,2)
2761
		fmul st0,st6 ;...*y0
2762
		fstp dword[opr_param]
2763
 
2764
		fld1
2765
		fsub st0,st1 ;1.-t
2766
		fmul st0,st1 ;(1.-t)*t
2767
		fadd st0,st0
2768
		fmul st0,st7 ;...*y1
2769
		mov esi,dword[opr_param]
2770
		fstp dword[opr_param]
2771
 
2772
		fldz
2773
		fadd st0,st1 ;0+t
2774
		fmul st0,st0 ;t*t
2775
		fimul word[coord_p2+2] ;...*y2
2776
 
2777
		fadd dword[opr_param]
2778
		mov dword[opr_param],esi
2779
		fadd dword[opr_param]
2780
		fistp word[v_poi_0+2] ;y
2781
 
2782
		mov eax,1
2783
		mov bx,word[v_poi_0+2]
2784
		mov cx,word[v_poi_0]
2785
		call draw_pixel
2786
 
2787
		fadd st0,st1 ;t+dt
2788
 
2789
		fld1
2790
		fcomp
2791
		fstsw ax
2792
		sahf
2793
	jae @b
2794
 
2795
	popad
2796
	ret
2797
endp
2798
 
2748 IgorA 2799
 
2800
 
2801
;*** функции для работы с воксельной графикой ***
2802
 
2803
 
2804
 
2805
;создание воксельных кистей
2806
align 4
2807
proc vox_brush_create uses eax ebx ecx edi, h_br:dword, buf_z:dword
2808
	mov edi,[h_br]
2809
	movzx ecx,byte[edi+3]
2810
	add edi,4
2811
 
2812
	; *** создание единичной кисти ***
2813
	mov eax,[buf_z]
2814
	mov buf2d_data,eax
2815
	movzx eax,byte[edi-4] ;ширина единичной кисти
2816
	mov buf2d_w,eax ;ширина буфера
2817
	movzx eax,byte[edi-4+1] ;высота единичной кисти
2818
	mov buf2d_h,eax ;высота буфера
2819
	mov buf2d_size_lt,0 ;отступ слева и справа для буфера
2820
	mov buf2d_color,0 ;цвет фона буфера
2821
	mov buf2d_bits,32 ;количество бит в 1-й точке изображения
2822
 
2823
	; *** создание следующих кистей ***
2824
	cmp ecx,1
2825
	jl .end_creat
2826
	movzx ebx,byte[edi-4+2] ;высота основания единичной кисти
2827
	shr ebx,1
2828
	cld
2829
	@@:
2830
		mov eax,edi
2831
		add edi,BUF_STRUCT_SIZE
2832
		stdcall vox_create_next_brush, eax, edi, ebx
2833
		shl ebx,1
2834
		loop @b
2835
	.end_creat:
2836
	ret
2837
endp
2838
 
2839
;удаление воксельных кистей
2840
align 4
2841
proc vox_brush_delete uses ecx edi, h_br:dword
2842
	mov edi,[h_br]
2843
	movzx ecx,byte[edi+3]
2844
	add edi,4
2845
 
2846
	; *** удаление кистей ***
2847
	cmp ecx,1
2848
	jl .end_delete
2849
	cld
2850
	@@:
2851
		add edi,BUF_STRUCT_SIZE
2852
		stdcall buf_delete, edi
2853
		loop @b
2854
	.end_delete:
2855
	ret
2856
endp
2857
 
2858
;функция для создания вокселя следующего порядка
2859
; buf_v1 - буфер с исходным вокселем
2860
; buf_v2 - буфер с увеличеным вокселем
2861
; h - высота основания исходного вокселя : 2
2862
align 4
2863
proc vox_create_next_brush uses eax ebx ecx edx edi, buf_v1:dword, buf_v2:dword, h:dword
2864
	mov edi,[buf_v1]
2865
	mov ebx,buf2d_h
2866
	mov ecx,buf2d_w
2867
	mov edi,[buf_v2]
2868
	mov buf2d_h,ebx
2869
	shl buf2d_h,1
2870
	mov buf2d_w,ecx
2871
	shl buf2d_w,1
2872
	mov buf2d_color,0
2873
	mov buf2d_bits,32
2874
 
2875
	stdcall buf_create, [buf_v2] ;создание буфера глубины
2876
	shr ecx,1
2877
	mov edx,[h]
2878
	shl edx,1
2879
	sub ebx,edx
2880
	;ecx - ширина исходного вокселя : 2
2881
	;ebx - высота исходного вокселя (без основания)
2882
	;edx - высота основания исходного вокселя
2883
	stdcall vox_add, [buf_v2], [buf_v1], ecx,0,0
2884
	stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,0
2885
 
2886
	mov eax,[h]
2887
	stdcall vox_add, [buf_v2], [buf_v1], 0,eax,eax
2888
	push eax ;stdcall ...
2889
	add eax,ebx
2890
	stdcall vox_add, [buf_v2], [buf_v1], 0,eax ;,...
2891
	sub eax,ebx
2892
 
2893
	shl ecx,1
2894
	;ecx - ширина исходного вокселя
2895
	mov eax,[h]
2896
	stdcall vox_add, [buf_v2], [buf_v1], ecx,eax,eax
2897
	push eax ;stdcall ...,[h]
2898
	add eax,ebx
2899
	stdcall vox_add, [buf_v2], [buf_v1], ecx,eax;,[h]
2900
	;sub eax,ebx
2901
	shr ecx,1
2902
 
2903
	;ecx - ширина исходного вокселя : 2
2904
	stdcall vox_add, [buf_v2], [buf_v1], ecx,edx,edx
2905
	add ebx,edx
2906
	stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,edx
2907
 
2908
	ret
2909
endp
2910
 
2911
;
2912
align 4
2758 IgorA 2913
proc vox_add, buf_v1:dword, buf_v2:dword, coord_x:dword, coord_y:dword, coord_z:dword
2748 IgorA 2914
pushad
2759 IgorA 2915
	mov ebx,[coord_x]
2916
	mov eax,[coord_y]
2748 IgorA 2917
	mov edi,[buf_v2]
2918
	mov ecx,buf2d_h
2919
	mov esi,buf2d_w
2920
	imul ecx,esi
2759 IgorA 2921
	add esi,ebx
2748 IgorA 2922
	mov edx,buf2d_data
2923
	cld
2924
	;ecx - count pixels in voxel
2925
	;edx - указатель на данные в воксельном буфере
2926
	;edi - указатель на воксельный буфер
2927
	;esi - width voxel buffer add coord x
2928
	.cycle:
2929
		cmp dword[edx],0
2930
		je @f
2931
			;проверяем буфер глубины
2759 IgorA 2932
			push eax ecx edi esi
2748 IgorA 2933
			mov ecx,eax
2759 IgorA 2934
			mov edi,[buf_v1]
2935
			call get_pixel_32 ;stdcall buf_get_pixel, [buf_v1],ebx,ecx
2748 IgorA 2936
			mov esi,[edx]
2937
			add esi,[coord_z]
2938
			cmp eax,esi
2939
			jge .end_draw
2759 IgorA 2940
			stdcall buf_set_pixel, [buf_v1],ebx,ecx,esi ;esi = new coord z
2748 IgorA 2941
			.end_draw:
2759 IgorA 2942
			pop esi edi ecx eax
2748 IgorA 2943
		@@:
2944
		add edx,4
2759 IgorA 2945
		inc ebx
2946
		cmp ebx,esi
2748 IgorA 2947
		jl @f
2759 IgorA 2948
			inc eax
2949
			sub ebx,buf2d_w
2748 IgorA 2950
		@@:
2951
		loop .cycle
2952
popad
2953
	ret
2954
endp
2955
 
2758 IgorA 2956
;description:
2957
; возврашает ширину воксельного изображения с 3-мя гранями
2958
; принимает указатель на кисть и масштаб
2959
align 4
2960
proc buf_vox_obj_get_img_w_3g uses ecx, h_br:dword,k_scale:dword
2961
	mov ecx,[h_br]
2962
 
2963
	movzx eax,byte[ecx]
2964
	cmp dword[k_scale],1
2965
	jl .end_c0
2966
		mov ecx,[k_scale]
2967
		shl eax,cl
2968
	.end_c0:
2969
	ret
2970
endp
2971
 
2972
;description:
2973
; возврашает высоту воксельного изображения с 3-мя гранями
2974
; принимает указатель на кисть и масштаб
2975
align 4
2976
proc buf_vox_obj_get_img_h_3g uses ecx, h_br:dword,k_scale:dword
2977
	mov ecx,[h_br]
2978
 
2979
	movzx eax,byte[ecx+1]
2980
	cmp dword[k_scale],1
2981
	jl .end_c0
2982
		mov ecx,[k_scale]
2983
		shl eax,cl
2984
	.end_c0:
2985
	ret
2986
endp
2987
 
2988
;description:
2815 IgorA 2989
; функция рисующая воксельный объект (видна 1 грань)
2758 IgorA 2990
;input:
2991
; buf_i - буфер в котором рисуется (24 бита)
2992
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2815 IgorA 2993
align 4
2994
proc buf_vox_obj_draw_1g, buf_i:dword, buf_z:dword, v_obj:dword, coord_x:dword,\
2995
coord_y:dword, k_scale:dword
2996
	cmp [k_scale],0
2997
	jl .end_f
2998
pushad
2999
	mov edi,[buf_i]
3000
	cmp buf2d_bits,24
3001
	jne .error1
3002
	mov edi,[buf_z]
3003
	cmp buf2d_bits,32
3004
	jne .error2
3005
 
3006
	mov ecx,[k_scale]
3007
	mov ebx,[coord_x]
3008
	mov edx,[coord_y]
3009
	mov edi,[v_obj]
3010
	add edi,vox_offs_data
3011
	xor esi,esi
3012
	stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
3013
 
3014
	jmp .end_0
3015
	.error1:
3016
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n24b
3017
		jmp .end_0
3018
	.error2:
3019
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n32b
3020
	.end_0:
3021
popad
3022
	.end_f:
3023
	ret
3024
endp
3025
 
3026
;input:
3027
; ebx - coord_x
3028
; edx - coord_y
3029
; esi - coord_z
3030
; ecx - уровень текушего узла
3031
; edi - указатель на данные воксельного объекта
3032
align 4
3033
proc draw_sub_vox_obj_1g, buf_i:dword, buf_z:dword, v_obj:dword
3034
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
3035
	je .sub_trees
3036
 
3037
		;прорисовка рамки если размер узла = 1
3038
		cmp ecx,0
3039
		jne @f
3040
			;проверка глубины esi
3041
			stdcall buf_get_pixel, [buf_z], ebx,edx, esi
3042
			cmp eax,esi
3043
			jge @f
3044
				push ecx
3045
				mov ecx,dword[edi]
3046
				and ecx,0xffffff
3047
				stdcall buf_set_pixel, [buf_i], ebx,edx, ecx
3048
				stdcall buf_set_pixel, [buf_z], ebx,edx, esi
3049
				pop ecx
3050
		@@:
3051
 
3052
		;рекурсивный перебор поддеревьев
3053
		push edx
3054
		;вход внутрь узла
3055
		dec ecx
3056
 
3057
		mov eax,1
3058
		cmp ecx,1
3059
		jl @f
3060
			shl eax,cl
3061
		@@:
3062
 
3063
		add edx,eax ;коректировка высоты под воксель нижнего уровня
3064
 
3065
		mov ah,byte[edi+3]
3066
		add edi,4
3067
		mov al,8
3068
		.cycle:
3069
			bt ax,8 ;тестируем только ah
3070
			jnc .c_next
3071
				push eax ebx edx esi
3072
				stdcall vox_corect_coords_pl, [v_obj],1
3073
				stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
3074
				pop esi edx ebx eax
3075
			.c_next:
3076
			shr ah,1
3077
			dec al
3078
			jnz .cycle
3079
		;выход из узла
3080
		inc ecx
3081
		pop edx
3082
		jmp .end_f
3083
	.sub_trees:
3084
		cmp ecx,0
3085
		jl .end_0 ;не рисуем очень маленькие воксели
3086
 
3087
			;рисуем узел
3088
			mov eax,[edi]
3089
			and eax,0xffffff
3090
 
3091
			cmp ecx,1
3092
			jl @f
3093
				;квадрат больше текущего масштаба
3094
				stdcall vox_draw_square_1g, [buf_i],[buf_z],eax
3095
				jmp .end_0
3096
			@@:
3097
				;квадрат текущего масштаба
3098
				push ecx
3099
				mov ecx,eax
3100
				stdcall buf_get_pixel, [buf_z], ebx,edx
3101
				cmp eax,esi
3102
				jge .end_1
3103
				stdcall buf_set_pixel, [buf_i], ebx,edx,ecx
3104
				stdcall buf_set_pixel, [buf_z], ebx,edx,esi
3105
				.end_1:
3106
				pop ecx
3107
		.end_0:
3108
		add edi,4
3109
	.end_f:
3110
	ret
3111
endp
3112
 
3113
;output:
3114
; eax - разрушается
3115
align 4
3116
proc vox_draw_square_1g uses ecx edx edi, buf_i:dword, buf_z:dword, color:dword
3117
locals
3118
	img_size dd ?
3119
	coord_y dd ?
3120
endl
3121
	mov edi,[buf_z]
3122
	xor eax,eax
3123
	inc eax
3124
	shl eax,cl
3125
	mov [img_size],eax
3126
	mov [coord_y],eax
3127
	.cycle_0:
3128
	push ebx
3129
	mov ecx,[img_size]
3130
	cld
3131
	.cycle_1:
3132
		push ecx
3133
		mov ecx,edx
3134
		call get_pixel_32
3135
		pop ecx
3136
		cmp eax,esi
3137
		jge @f
3138
			stdcall buf_set_pixel, [buf_i], ebx,edx, [color]
3139
			stdcall buf_set_pixel, edi, ebx,edx, esi
3140
		@@:
3141
		inc ebx
3142
	loop .cycle_1
3143
	pop ebx
3144
	inc edx
3145
	dec dword[coord_y]
3146
	jnz .cycle_0
3147
	ret
3148
endp
3149
 
3150
;description:
3151
; функция рисующая воксельный объект (видно 3 грани)
3152
;input:
3153
; buf_i - буфер в котором рисуется (24 бита)
3154
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2758 IgorA 3155
; h_br - кисть с изображениями вокселей (32 бита)
3156
; v_obj - воксельный объект
3157
; k_scale - коэф. для масштабирования изображения
3158
align 4
3159
proc buf_vox_obj_draw_3g, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
3160
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword
3161
pushad
3162
	mov edi,[v_obj]
3163
	mov ecx,[k_scale]
3164
	mov ebx,[coord_x]
3165
	mov edx,[coord_y]
3166
	add edi,vox_offs_data
3167
	mov esi,[coord_z]
3168
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
3169
popad
3170
	ret
3171
endp
3172
 
3173
;description:
3174
; функция рисующая часть воксельного объекта
3175
;input:
3176
; buf_i - буфер в котором рисуется (24 бита)
3177
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
3178
; h_br - кисть с изображениями вокселей (32 бита)
3179
; v_obj - воксельный объект
3180
; k_scale - коэф. для масштабирования изображения
3181
align 4
3182
proc buf_vox_obj_draw_3g_scaled, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
3183
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword,\
3184
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword,b_color:dword
3185
pushad
3186
locals
3187
	p_node dd 0 ;родительский узел
3188
endl
3189
	mov edi,[v_obj]
3190
	add edi,vox_offs_data
3191
 
3192
	mov ecx,[k_scale]
3193
	mov ebx,[coord_x]
3194
 
3195
	;тестовая рамка
3196
	mov eax,[h_br]
3197
 
3198
	movzx edx,byte[eax]
3199
	movzx esi,byte[eax+1]
3200
	cmp ecx,1
3201
	jl .end_c0
3202
		shl edx,cl
3203
		shl esi,cl
3204
	.end_c0:
3205
	;stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
3206
 
3207
	;вертикальная полоса
3208
	add ebx,edx
3209
	shr edx,cl
3210
	stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
3211
	mov ecx,[s_k_scale]
3212
	shr esi,cl
3213
	xor eax,eax
3214
	inc eax
3215
	shl eax,cl
3216
	dec eax
3217
	sub eax,[s_c_z] ;значения по оси z возрастают с низу вверх
3218
	imul eax,esi
3219
	add eax,[coord_y]
3220
	stdcall buf_filled_rect_by_size, [buf_i], ebx,eax,edx,esi, [b_color]
3221
	mov ebx,[coord_y]
3222
	shl esi,cl
3223
	add ebx,esi
3224
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
3225
	shr eax,1
3226
	mov esi,[h_br]
3227
	movzx esi,byte[esi+1]
3228
	;ползунок
3229
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,eax,esi, [s_c_x], [s_k_scale], [b_color]
3230
	mov edx,[coord_x]
3231
	add edx,eax
3232
	;ползунок
3233
	stdcall draw_polz_hor, [buf_i], edx,ebx,eax,esi, [s_c_y], [s_k_scale], [b_color]
3234
;---
3235
 
3236
	mov esi,[s_k_scale]
3237
	cmp esi,1
3238
	jl .end_2
3239
 
3240
	; *** (1) ***
3241
	.found:
3242
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
3243
	movzx bx,byte[edi+3]
3244
	mov [p_node],edi
3245
	add edi,4
3246
	cmp eax,0
3247
	je .end_1
3248
	mov ecx,eax
3249
	cld
3250
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
3251
		bt bx,0 ;проверяем есть ли дочерние узлы
3252
		jnc .end_0
3253
			xor eax,eax
3254
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
3255
		.end_0:
3256
		shr bx,1
3257
		loop @b
3258
	.end_1:
3259
	bt bx,0
3260
	jnc .end_2 ;если поддерева не существует
3261
	dec esi
3262
	cmp esi,0
3263
	jg .found
3264
 
3265
	; *** (2) ***
3266
	;рисование части объекта
3267
	mov ecx,[k_scale]
3268
	mov ebx,[coord_x]
3269
	mov edx,[coord_y]
3270
	mov esi,[coord_z]
3271
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
3272
	.end_2:
3273
 
3274
popad
3275
	ret
3276
endp
3277
 
3278
;input:
3279
; h_br - кисть с изображениями вокселей (32 бита)
3280
; ebx - coord_x
3281
; edx - coord_y
3282
; esi - coord_z
3283
; ecx - уровень текушего узла
3284
; edi - указатель на данные воксельного объекта
3285
align 4
3286
proc vox_go_in_node, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword
3287
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
3288
	je .sub_trees
3289
		;рекурсивный перебор поддеревьев
3290
		push eax edx
3291
 
3292
		;прорисовка рамки если размер узла = 1
3293
		cmp ecx,0
3294
		jne .end_2
3295
			push eax
3296
				stdcall vox_get_sub_brush,[h_br],0 ;определяем кисть для рисования
3297
				cmp eax,0 ;если кисть не найдена
3298
				je @f
3299
					stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
3300
				@@:
3301
			pop eax
3302
		.end_2:
3303
 
3304
		;вход внутрь узла
3305
		dec ecx
3306
;---
3307
		push ebx
3308
			;mov eax,(h-h_osn/2)
3309
			mov ebx,[h_br]
3310
			movzx eax,byte[ebx+1]
3311
			movzx ebx,byte[ebx+2]
3312
			shr ebx,1
3313
			sub eax,ebx
3314
		cmp ecx,1
3315
		jl .end_c1
3316
			shl eax,cl
3317
			shl ebx,cl
3318
		.end_c1:
3319
		add esi,ebx
3320
		pop ebx
3321
		add edx,eax ;коректировка высоты под воксель нижнего уровня
3322
;---
3323
		mov ah,byte[edi+3]
3324
		add edi,4
3325
		mov al,8
3326
		.cycle:
3327
			bt ax,8 ;тестируем только ah
3328
			jnc .c_next
3329
				push ebx edx esi
3330
				stdcall vox_corect_coords, [h_br], [v_obj]
3331
				stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
3332
				pop esi edx ebx
3333
			.c_next:
3334
			shr ah,1
3335
			dec al
3336
			jnz .cycle
3337
 
3338
		;выход из узла
3339
		inc ecx
3340
		pop edx eax
3341
 
3342
		jmp .end_f
3343
	.sub_trees:
3344
		;рисуем узел
3345
		push eax
3346
			stdcall vox_get_sub_brush,[h_br],ecx ;определяем кисть для рисования
3347
			cmp eax,0 ;если кисть не найдена
3348
			je @f
3349
				stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
3350
			@@:
3351
		pop eax
3352
 
3353
		add edi,4
3354
	.end_f:
3355
	ret
3356
endp
3357
 
3358
;description:
3359
; функция рисующая одиночный воксел
3360
;input:
3361
; buf_i - буфер в котором рисуется (24 бита)
3362
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
3363
; buf_v - буфер с изображением вокселя (32 бита)
3364
; v_color - цвет
3365
align 4
3366
proc draw_vox, buf_i:dword, buf_z:dword, buf_v:dword,\
3367
coord_x:dword, coord_y:dword, coord_z:dword, v_color:dword
3368
pushad
3369
	mov eax,[coord_x]
3370
	mov ebx,[coord_y]
3371
	mov edi,[buf_v]
3372
	mov ecx,buf2d_h
3373
	mov esi,buf2d_w
3374
	imul ecx,esi
3375
	add esi,eax
3376
	mov edx,buf2d_data
3377
	cld
3378
	;ecx - count pixels in voxel
3379
	;edx - указатель на данные в воксельном буфере
3380
	;edi - указатель на воксельный буфер
3381
	;esi - width voxel buffer add coord x
3382
	.cycle:
3383
		cmp dword[edx],0
3384
		je @f
3385
			;проверяем буфер глубины
3386
			push eax
3387
			stdcall buf_get_pixel, [buf_z],eax,ebx
3388
			sub eax,[coord_z]
3389
			cmp eax,[edx]
3390
			jl .dr_pixel
3391
				pop eax
3392
				jmp @f
3393
			.dr_pixel:
3394
				;рисуем точку
3395
				pop eax
3396
				stdcall buf_set_pixel, [buf_i],eax,ebx,[v_color]
3397
				push ecx
3398
				mov ecx,[coord_z]
3399
				add ecx,[edx]
3400
				stdcall buf_set_pixel, [buf_z],eax,ebx,ecx
3401
				pop ecx
3402
		@@:
3403
		add edx,4
3404
		inc eax
3405
		cmp eax,esi
3406
		jl @f
3407
			inc ebx
3408
			sub eax,buf2d_w
3409
		@@:
3410
		loop .cycle
3411
popad
3412
	ret
3413
endp
3414
 
3415
;description:
3416
;функция для коректировки координат
3417
;направления осей координат в вокселе:
3418
;*z
3419
;|
3420
;+
3421
;  * y
3422
; /
3423
;+
3424
; \
3425
;  * x
3426
;input:
3427
;  al - номер узла в дереве (от 1 до 8)
3428
; ebx - координата x
3429
; edx - координата y
3430
; esi - координата z
3431
; ecx - уровень текушего узла
3432
;output:
3433
; ebx - новая координата x
3434
; edx - новая координата y
3435
; esi - новая координата z
3436
align 4
3437
proc vox_corect_coords, h_br:dword, v_obj:dword
3438
locals
3439
	osn_w_2 dd ? ;ширина основания единичного вокселя : 2
3440
	vox_h dd ? ;высота единичного вокселя
3441
endl
3442
	cmp ecx,0
3443
	jl .end_f ;для ускорения отрисовки
3444
 
3445
	push eax edi
3446
	and eax,15 ;выделяем номер узла в дереве
3447
	mov edi,[v_obj]
3448
	add edi,vox_offs_tree_table
3449
	add edi,8
3450
	sub edi,eax
3451
 
3452
	push ebx ecx
3453
		mov ebx,[h_br]
3454
 
3455
		movzx ecx,byte[ebx]
3456
		shr ecx,1
3457
		mov dword[osn_w_2],ecx
3458
 
3459
		movzx ecx,byte[ebx+2]
3460
		movzx ebx,byte[ebx+1]
3461
		sub ebx,ecx
3462
		mov dword[vox_h],ebx
3463
		shr ecx,1
3464
		mov eax,ecx ;eax - высота основания единичного вокселя : 2
3465
	pop ecx ebx
3466
 
3467
	cmp ecx,1
3468
	jl .no_scale ;во избежание зацикливания
3469
		shl eax,cl
3470
		shl dword[osn_w_2],cl
3471
		shl dword[vox_h],cl
3472
	.no_scale:
3473
 
3474
;	add esi,eax ;меняем глубину для буфера z (компенсация для координаты y)
3475
	bt word[edi],0 ;test voxel coord x
3476
	jnc @f
3477
		add ebx,[osn_w_2]
3478
		add edx,eax
3479
		add esi,eax ;меняем глубину для буфера z
3480
	@@:
3481
	bt word[edi],1 ;test voxel coord y
3482
	jnc @f
3483
		add ebx,[osn_w_2]
3484
		sub edx,eax
3485
		sub esi,eax ;меняем глубину для буфера z
3486
	@@:
3487
	bt word[edi],2 ;test voxel coord z
3488
	jnc @f
3489
		sub edx,[vox_h]
3490
	@@:
3491
	pop edi eax
3492
	.end_f:
3493
	ret
3494
endp
3495
 
3496
;извлекаем из h_br указатель на буфер с изображением вокселя, указанного порядка n
3497
align 4
3498
proc vox_get_sub_brush uses ebx ecx, h_br:dword, n:dword
3499
	xor eax,eax
3500
	mov ebx,[n]
3501
	cmp ebx,0
3502
	jl @f
3503
	mov ecx,[h_br]
3504
	cmp bl,byte[ecx+3]
3505
	jg @f
3506
		add ecx,4
3507
		imul ebx,BUF_STRUCT_SIZE
3508
		mov eax,ebx
3509
		add eax,ecx
3510
	@@:
3511
	ret
3512
endp
3513
 
3514
;description:
3515
; функция рисующая срез воксельного обьекта
3516
;input:
3517
; v_size - размер квадрата с вокселем
3518
; k_scale - степень детализации изображения
3519
; n_plane - номер плоскости сечния (в пределах от 0 до 2^k_scale - 1)
3520
; b_color - цвет границы
3521
align 4
3522
proc buf_vox_obj_draw_pl, buf_i:dword, v_obj:dword, coord_x:dword,\
3523
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword
3524
	cmp [k_scale],0
3525
	jl .end_f
3526
pushad
3527
	mov eax,[v_size]
3528
	mov ecx,[k_scale]
3529
	mov ebx,eax
3530
	cmp ecx,1
3531
	jl @f
3532
		shl ebx,cl
3533
	@@:
3534
	;ebx - полный размер изображения
3535
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
3536
	mov edx,ebx
3537
	add ebx,[coord_y]
3538
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
3539
 
3540
	;рисование точек для сетки
3541
	push ecx
3542
	mov edi,1
3543
	cmp ecx,1
3544
	jl @f
3545
		shl edi,cl
3546
	@@:
3547
	dec edi
3548
	cmp edi,1
3549
	jl .end_0
3550
	mov ecx,edi
3551
	imul ecx,edi
3552
	mov ebx,[coord_x]
3553
	mov edx,[coord_y]
3554
	add edx,eax
3555
	xor esi,esi
3556
	cld
3557
	@@:
3558
		add ebx,eax
3559
		inc esi
3560
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
3561
		cmp esi,edi
3562
		jl .end_1
3563
			;переход точек на новую строку
3564
			xor esi,esi
3565
			mov ebx,[coord_x]
3566
			add edx,eax
3567
		.end_1:
3568
		loop @b
3569
	.end_0:
3570
	pop ecx
3571
 
3572
	;eax - размер одного квадрата
2815 IgorA 3573
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 3574
	mov ebx,[coord_x]
3575
	mov edx,[coord_y]
3576
	mov edi,[v_obj]
3577
	add edi,vox_offs_data
3578
	xor esi,esi
3579
	push eax
2815 IgorA 3580
	mov eax,1
3581
	shl eax,cl
3582
	dec eax
3583
	sub eax,[n_plane]
3584
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],eax
2758 IgorA 3585
popad
3586
	.end_f:
3587
	ret
3588
endp
3589
 
3590
;description:
3591
; функция рисующая срез части воксельного обьекта
3592
;input:
3593
; s_c_x, s_c_y, s_c_z, s_k_scale - параметры определяющие часть воксельного объекта, которая будет рисоваться
3594
align 4
3595
proc buf_vox_obj_draw_pl_scaled, buf_i:dword, v_obj:dword, coord_x:dword,\
3596
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword,\
3597
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword
3598
	cmp [k_scale],0
3599
	jl .end_f
3600
pushad
3601
locals
3602
	p_node dd 0 ;родительский узел
3603
endl
3604
	mov eax,[v_size]
3605
	mov ecx,[k_scale]
3606
	mov ebx,eax
3607
	cmp ecx,1
3608
	jl @f
3609
		shl ebx,cl
3610
	@@:
3611
	;ebx - полный размер изображения
3612
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
3613
	mov edx,ebx
3614
	add ebx,[coord_y]
3615
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
3616
 
3617
	;рисование точек для сетки
3618
	push ecx
3619
	mov edi,1
3620
	cmp ecx,1
3621
	jl @f
3622
		shl edi,cl
3623
	@@:
3624
	dec edi
3625
	cmp edi,1
3626
	jl .end_3
3627
	mov ecx,edi
3628
	imul ecx,edi
3629
	mov ebx,[coord_x]
3630
	mov edx,[coord_y]
3631
	add edx,eax
3632
	xor esi,esi
3633
	cld
3634
	@@:
3635
		add ebx,eax
3636
		inc esi
3637
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
3638
		cmp esi,edi
3639
		jl .end_4
3640
			;переход точек на новую строку
3641
			xor esi,esi
3642
			mov ebx,[coord_x]
3643
			add edx,eax
3644
		.end_4:
3645
		loop @b
3646
	.end_3:
3647
	pop ecx
3648
 
3649
	mov esi,[s_k_scale]
3650
	cmp esi,1
3651
	jl .end_2
3652
	mov edi,[v_obj]
3653
	add edi,vox_offs_data
3654
 
3655
	; *** (1) ***
3656
	.found:
3657
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
3658
	movzx bx,byte[edi+3]
3659
	mov [p_node],edi
3660
	add edi,4
3661
	cmp eax,0
3662
	je .end_1
3663
	mov ecx,eax
3664
	cld
3665
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
3666
		bt bx,0 ;проверяем есть ли дочерние узлы
3667
		jnc .end_0
3668
			xor eax,eax
3669
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
3670
		.end_0:
3671
		shr bx,1
3672
		loop @b
3673
	.end_1:
3674
	bt bx,0
3675
	jnc .end_2 ;если поддерева не существует
3676
	dec esi
3677
	cmp esi,0
3678
	jg .found
3679
 
3680
	mov eax,[v_size]
3681
	;eax - размер одного квадрата
2815 IgorA 3682
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 3683
	mov ecx,[k_scale]
3684
	mov ebx,[coord_x]
3685
	mov edx,[coord_y]
3686
	xor esi,esi
3687
	push eax
2815 IgorA 3688
	mov eax,1
3689
	shl eax,cl
3690
	dec eax
3691
	sub eax,[n_plane]
2758 IgorA 3692
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj], eax
3693
 
3694
	.end_2:
3695
popad
3696
	.end_f:
3697
	ret
3698
endp
3699
 
3700
;description:
3701
; определение позиции узла в дереве (от 0 до 7)
3702
align 4
3703
proc vox_obj_get_node_position uses ebx ecx edi, v_obj:dword,\
3704
coord_x:dword,coord_y:dword,coord_z:dword,k_scale:dword
3705
	mov ecx,[k_scale]
3706
	dec ecx
3707
	mov eax,[coord_x]
3708
	mov ebx,[coord_y]
3709
	mov edi,[coord_z]
3710
	cmp ecx,1
3711
	jl .end_0
3712
		shr eax,cl
3713
		shr ebx,cl
3714
		shr edi,cl
3715
	.end_0:
3716
	and eax,1
3717
	bt ebx,0
3718
	jnc @f
3719
		bts eax,1
3720
	@@:
3721
	bt edi,0
3722
	jnc @f
3723
		bts eax,2
3724
	@@:
3725
 
3726
	mov edi,[v_obj]
3727
	add edi,vox_offs_tree_table
3728
	@@:
3729
		cmp al,byte[edi]
3730
		je @f
3731
		inc edi
3732
		jmp @b
3733
	@@:
3734
	sub edi,[v_obj]
3735
	sub edi,vox_offs_tree_table
3736
	mov eax,edi
3737
 
3738
	ret
3739
endp
3740
 
3741
;input:
3742
; edi - указатель на данные воксельного объекта
3743
;output:
3744
; eax - eax + число узлов в данных вокс. объекта
3745
; edi - указатель на смещенные данные вокс. объекта
3746
align 4
3747
proc vox_obj_rec0
3748
	inc eax
3749
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
3750
	je .sub_trees
3751
 
3752
		;рекурсивный перебор поддеревьев
3753
		push ebx ecx
3754
		mov bh,byte[edi+3]
3755
		add edi,4
3756
		mov bl,8
3757
		.cycle:
3758
			bt bx,8 ;тестируем только bh
3759
			jnc .c_next
3760
				stdcall vox_obj_rec0
3761
			.c_next:
3762
			shr bh,1
3763
			dec bl
3764
			jnz .cycle
3765
		pop ecx ebx
3766
 
3767
		jmp .end_f
3768
	.sub_trees:
3769
		add edi,4
3770
	.end_f:
3771
	ret
3772
endp
3773
 
3774
;description:
3775
; функция рисующая горизонтальную полосу с ползунком
3776
align 4
3777
proc draw_polz_hor uses eax ebx ecx, buf:dword, coord_x:dword, coord_y:dword,\
3778
size_x:dword, size_y:dword, pos:dword, k_scale:dword, color:dword
3779
	mov ebx,[size_x]
3780
	stdcall buf_rect_by_size, [buf], [coord_x],[coord_y],ebx,[size_y], [color]
3781
	mov ecx,[k_scale]
3782
	shr ebx,cl
3783
	mov eax,[pos]
3784
	imul eax,ebx
3785
	add eax,[coord_x]
3786
	stdcall buf_filled_rect_by_size, [buf], eax,[coord_y],ebx,[size_y], [color]
3787
	ret
3788
endp
3789
 
3790
;input:
3791
; ebx - coord_x
3792
; edx - coord_y
3793
; esi - coord_z
3794
; ecx - уровень текушего узла
3795
; edi - указатель на данные воксельного объекта
3796
align 4
3797
proc draw_sub_vox_obj_pl, buf_i:dword, v_obj:dword, clip_z:dword,\
3798
v_size:dword
3799
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
3800
	je .sub_trees
3801
 
3802
		;прорисовка рамки если размер узла = 1
3803
		cmp ecx,0
3804
		jne @f
2815 IgorA 3805
			;проверка глубины esi
3806
			;clip_z=n_plane
3807
			stdcall vox_is_clip, [clip_z];,[v_size]
3808
			cmp eax,0
3809
			je @f
3810
				push ecx
3811
				mov ecx,dword[edi]
3812
				and ecx,0xffffff
3813
				stdcall buf_rect_by_size, [buf_i], ebx,edx, [v_size],[v_size],ecx
3814
				pop ecx
2758 IgorA 3815
		@@:
3816
 
3817
		;рекурсивный перебор поддеревьев
3818
		push edx
3819
		;вход внутрь узла
3820
		dec ecx
3821
 
3822
		mov eax,[v_size]
3823
		cmp ecx,1
3824
		jl @f
3825
			shl eax,cl
3826
		@@:
2815 IgorA 3827
 
2758 IgorA 3828
		add edx,eax ;коректировка высоты под воксель нижнего уровня
3829
 
3830
		mov ah,byte[edi+3]
3831
		add edi,4
3832
		mov al,8
3833
		.cycle:
3834
			bt ax,8 ;тестируем только ah
3835
			jnc .c_next
3836
				push eax ebx edx esi
3837
				stdcall vox_corect_coords_pl, [v_obj],[v_size]
3838
				stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],[clip_z],[v_size]
3839
				pop esi edx ebx eax
3840
			.c_next:
3841
			shr ah,1
3842
			dec al
3843
			jnz .cycle
3844
		;выход из узла
3845
		inc ecx
3846
		pop edx
3847
		jmp .end_f
3848
	.sub_trees:
3849
		cmp ecx,0
3850
		jl .end_0 ;не рисуем очень маленькие воксели
3851
 
2815 IgorA 3852
			;проверка глубины esi
3853
			;clip_z=n_plane
3854
			stdcall vox_is_clip, [clip_z]
3855
			cmp eax,0
3856
			je .end_0
2758 IgorA 3857
 
2815 IgorA 3858
			;рисуем узел
3859
			mov eax,[edi]
3860
			and eax,0xffffff
3861
			push eax ;цвет узла
2758 IgorA 3862
 
2815 IgorA 3863
			mov eax,[v_size]
3864
			cmp ecx,1
3865
			jl @f
3866
				;квадрат больше текущего масштаба
3867
				shl eax,cl ;размер узла
3868
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
3869
				push ebx edx esi
3870
				mov esi,eax
3871
				inc ebx
3872
				inc edx
3873
				sub esi,2
3874
				mov eax,[buf_i]
3875
				push dword 128
3876
				push dword[eax+16] ;+16 - b_color
3877
				stdcall combine_colors_3,[edi]
3878
				stdcall buf_rect_by_size, [buf_i], ebx,edx, esi,esi,eax
3879
				pop esi edx ebx
3880
				jmp .end_0
3881
			@@:
3882
				;квадрат текущего масштаба
3883
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
2758 IgorA 3884
		.end_0:
3885
		add edi,4
3886
	.end_f:
3887
	ret
3888
endp
3889
 
3890
;description:
3891
; вспомогательная функция для проверки глубины esi
3892
;input:
3893
; ecx - уровень текушего узла
3894
; esi - coord z
2815 IgorA 3895
; clip_z - n_plane
2758 IgorA 3896
;output:
3897
; eax - 0 if no draw, 1 if draw
3898
align 4
2815 IgorA 3899
proc vox_is_clip uses ebx edi, clip_z:dword
2758 IgorA 3900
	xor eax,eax
3901
	mov ebx,[clip_z]
2815 IgorA 3902
	mov edi,1
2758 IgorA 3903
	cmp ecx,1
3904
	jl @f
3905
		shl edi,cl
3906
	@@:
3907
	;edi = 2^ecx
3908
	add edi,esi
2815 IgorA 3909
	cmp edi,ebx ;if (esi+2^ecx <= n_plane) no draw
2758 IgorA 3910
	jle @f
2815 IgorA 3911
	inc ebx
3912
	cmp esi,ebx ;if (esi >= (n_plane+1)) no draw
2758 IgorA 3913
	jge @f
3914
		inc eax
3915
	@@:
3916
	ret
3917
endp
3918
 
3919
;функция для коректировки координат
3920
;направления осей координат в вокселе:
3921
;*z
3922
;|
3923
;+-* x
3924
;input:
3925
;  al - номер узла в дереве (от 1 до 8)
3926
; ebx - координата x
3927
; edx - координата y
3928
; esi - координата z
3929
; ecx - уровень текушего узла
3930
;output:
3931
; ebx - новая координата x
3932
; edx - новая координата y
3933
; esi - новая координата z
3934
align 4
3935
proc vox_corect_coords_pl, v_obj:dword, v_size:dword
3936
	cmp ecx,0
3937
	jl .end_f ;для ускорения отрисовки
3938
 
3939
	push eax edi
3940
	and eax,15 ;выделяем номер узла в дереве
3941
	mov edi,[v_obj]
3942
	add edi,vox_offs_tree_table
3943
	add edi,8
3944
	sub edi,eax
3945
 
2815 IgorA 3946
	mov eax,[v_size]
2758 IgorA 3947
	cmp ecx,1
2815 IgorA 3948
	jl @f
2758 IgorA 3949
		shl eax,cl
3950
	@@:
3951
 
3952
	bt word[edi],0 ;test voxel coord x
3953
	jnc @f
3954
		add ebx,eax
3955
	@@:
3956
	bt word[edi],2 ;test voxel coord z
3957
	jnc @f
3958
		sub edx,eax
3959
	@@:
2815 IgorA 3960
	bt word[edi],1 ;test voxel coord y
3961
	jc @f
3962
		mov eax,1
3963
		cmp ecx,1
3964
		jl .end_0
3965
			shl eax,cl
3966
		.end_0:
3967
		add esi,eax ;меняем глубину для буфера z
3968
	@@:
2758 IgorA 3969
	pop edi eax
3970
	.end_f:
3971
	ret
3972
endp
3973
 
3974
;description:
3975
; функция рисующая тени
3976
;input:
3977
; buf_i - буфер в котором рисуется (24 бита)
3978
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
3979
; h_br - кисть с изображениями вокселей (32 бита)
3980
; k_scale - коэф. для масштабирования изображения
3981
align 4
3982
proc buf_vox_obj_draw_3g_shadows, buf_i:dword, buf_z:dword, h_br:dword, \
3983
coord_x:dword, coord_y:dword, color:dword, k_scale:dword, prop:dword
3984
locals
3985
	correct_z dd 0 ;коректировка для буфера глубины
3986
endl
3987
pushad
3988
	mov eax,[k_scale]
3989
	add eax,[prop]
3990
	mov dword[correct_z],8
3991
	sub [correct_z],eax
3992
	mov ebx,[coord_x]
3993
	;correct_z = 8-k_scale-prop
3994
 
3995
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
3996
	mov edx,eax ;edx - ширина изображения
3997
	stdcall buf_vox_obj_get_img_h_3g, [h_br],[k_scale]
3998
	mov esi,eax
3999
 
4000
	mov edi,[coord_y]
4001
	mov ecx,edx
4002
	add edx,ebx ;ширина + отступ слева
4003
	imul ecx,esi
4004
	cld
4005
	.cycle_0:
4006
		stdcall buf_get_pixel, [buf_z],ebx,edi
4007
		cmp eax,0
4008
		je @f
4009
			stdcall vox_correct_z, [correct_z]
4010
			push eax
4011
			stdcall buf_get_pixel, [buf_i],ebx,edi
4012
			stdcall combine_colors_3,eax,[color] ;,eax
4013
			stdcall buf_set_pixel, [buf_i],ebx,edi,eax
4014
		@@:
4015
		inc ebx
4016
		cmp ebx,edx
4017
		jl @f
4018
			mov ebx,[coord_x]
4019
			inc edi
4020
		@@:
4021
		loop .cycle_0
4022
 
4023
popad
4024
	ret
4025
endp
4026
 
4027
;output:
4028
; eax - scaled coord z
4029
align 4
4030
proc vox_correct_z uses ecx, correct_z:dword
4031
	mov ecx,[correct_z]
4032
	cmp ecx,0
4033
	je .end_f
4034
	jl .end_0
4035
		shl eax,cl
4036
		jmp .end_f
4037
	.end_0:
4038
		neg ecx
4039
		inc ecx
4040
		shr eax,cl
4041
	.end_f:
4042
	ret
4043
endp
4044
 
4045
;output:
4046
; eax - color
4047
align 4
4048
proc combine_colors_3 uses ebx ecx edx edi esi, col_0:dword, col_1:dword, alpha:dword
4049
 
4050
	mov ebx,[col_0]
4051
	mov ecx,[col_1]
4052
	movzx di,byte[alpha] ;pro
4053
	mov si,0x00ff ;---get transparent---
4054
	sub si,di ;256-pro
4055
 
4056
	;---blye---
4057
	movzx ax,bl
4058
	imul ax,si
4059
	movzx dx,cl
4060
	imul dx,di
4061
	add ax,dx
4062
	mov cl,ah
4063
	;---green---
4064
	movzx ax,bh
4065
	imul ax,si
4066
	movzx dx,ch
4067
	imul dx,di
4068
	add ax,dx
4069
	mov ch,ah
4070
	shr ebx,16
4071
	ror ecx,16
4072
	;---red---
4073
	movzx ax,bl
4074
	imul ax,si
4075
	movzx dx,cl
4076
	imul dx,di
4077
	add ax,dx
4078
 
4079
	shl eax,8
4080
	ror ecx,16
4081
	mov ax,cx
4082
	and eax,0xffffff
4083
 
4084
	ret
4085
endp
4086
 
1535 IgorA 4087
txt_err_n8b db 'need buffer 8 bit',13,10,0
4088
txt_err_n24b db 'need buffer 24 bit',13,10,0
2815 IgorA 4089
txt_err_n32b db 'need buffer 32 bit',13,10,0
2358 IgorA 4090
txt_err_n8_24b db 'need buffer 8 or 24 bit',13,10,0
1535 IgorA 4091
 
4092
align 16
4093
EXPORTS:
4094
	dd sz_lib_init, lib_init
4095
	dd sz_buf2d_create, buf_create
4096
	dd sz_buf2d_create_f_img, buf_create_f_img
4097
	dd sz_buf2d_clear, buf_clear
4098
	dd sz_buf2d_draw, buf_draw_buf
4099
	dd sz_buf2d_delete, buf_delete
2136 IgorA 4100
	dd sz_buf2d_resize, buf_resize
1535 IgorA 4101
	dd sz_buf2d_line, buf_line_brs
2230 IgorA 4102
	dd sz_buf2d_line_sm, buf_line_brs_sm
1634 IgorA 4103
	dd sz_buf2d_rect_by_size, buf_rect_by_size
1642 IgorA 4104
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
1535 IgorA 4105
	dd sz_buf2d_circle, buf_circle
4106
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
4107
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
4108
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
4109
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
4110
	dd sz_buf2d_bit_blt, buf_bit_blt
4111
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
4112
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1727 IgorA 4113
	dd sz_buf2d_curve_bezier, buf_curve_bezier
1535 IgorA 4114
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
4115
	dd sz_buf2d_draw_text, buf_draw_text
4116
	dd sz_buf2d_crop_color, buf_crop_color
4117
	dd sz_buf2d_offset_h, buf_offset_h
1684 IgorA 4118
	dd sz_buf2d_flood_fill, buf_flood_fill
1910 IgorA 4119
	dd sz_buf2d_set_pixel, buf_set_pixel
2658 IgorA 4120
	dd sz_buf2d_get_pixel, buf_get_pixel
2748 IgorA 4121
	dd sz_buf2d_vox_brush_create, vox_brush_create
4122
	dd sz_buf2d_vox_brush_delete, vox_brush_delete
2758 IgorA 4123
	dd sz_buf2d_vox_obj_get_img_w_3g, buf_vox_obj_get_img_w_3g
4124
	dd sz_buf2d_vox_obj_get_img_h_3g, buf_vox_obj_get_img_h_3g
2815 IgorA 4125
	dd sz_buf2d_vox_obj_draw_1g, buf_vox_obj_draw_1g
2758 IgorA 4126
	dd sz_buf2d_vox_obj_draw_3g, buf_vox_obj_draw_3g
4127
	dd sz_buf2d_vox_obj_draw_3g_scaled, buf_vox_obj_draw_3g_scaled
4128
	dd sz_buf2d_vox_obj_draw_pl, buf_vox_obj_draw_pl
4129
	dd sz_buf2d_vox_obj_draw_pl_scaled, buf_vox_obj_draw_pl_scaled
4130
	dd sz_buf2d_vox_obj_draw_3g_shadows, buf_vox_obj_draw_3g_shadows
1535 IgorA 4131
	dd 0,0
4132
	sz_lib_init db 'lib_init',0
4133
	sz_buf2d_create db 'buf2d_create',0
4134
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
4135
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
4136
	sz_buf2d_draw db 'buf2d_draw',0
4137
	sz_buf2d_delete db 'buf2d_delete',0
2136 IgorA 4138
	sz_buf2d_resize db 'buf2d_resize',0
1535 IgorA 4139
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
2230 IgorA 4140
	sz_buf2d_line_sm db 'buf2d_line_sm',0 ;рисование сглаженной линии
1642 IgorA 4141
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;рисование рамки прямоугольника, 2-я координата задана по размеру
4142
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;рисование залитого прямоугольника, 2-я координата задана по размеру
1535 IgorA 4143
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
4144
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
4145
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
4146
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
4147
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
4148
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
4149
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
4150
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1727 IgorA 4151
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
1535 IgorA 4152
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
4153
	sz_buf2d_draw_text db 'buf2d_draw_text',0
4154
	sz_buf2d_crop_color db 'buf2d_crop_color',0
4155
	sz_buf2d_offset_h db 'buf2d_offset_h',0
1684 IgorA 4156
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
1910 IgorA 4157
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
2658 IgorA 4158
	sz_buf2d_get_pixel db 'buf2d_get_pixel',0
2748 IgorA 4159
	sz_buf2d_vox_brush_create db 'buf2d_vox_brush_create',0
4160
	sz_buf2d_vox_brush_delete db 'buf2d_vox_brush_delete',0
2758 IgorA 4161
	sz_buf2d_vox_obj_get_img_w_3g db 'buf2d_vox_obj_get_img_w_3g',0
4162
	sz_buf2d_vox_obj_get_img_h_3g db 'buf2d_vox_obj_get_img_h_3g',0
2815 IgorA 4163
	sz_buf2d_vox_obj_draw_1g db 'buf2d_vox_obj_draw_1g',0
2758 IgorA 4164
	sz_buf2d_vox_obj_draw_3g db 'buf2d_vox_obj_draw_3g',0
4165
	sz_buf2d_vox_obj_draw_3g_scaled db 'buf2d_vox_obj_draw_3g_scaled',0
4166
	sz_buf2d_vox_obj_draw_pl db 'buf2d_vox_obj_draw_pl',0
4167
	sz_buf2d_vox_obj_draw_pl_scaled db 'buf2d_vox_obj_draw_pl_scaled',0
4168
	sz_buf2d_vox_obj_draw_3g_shadows db 'buf2d_vox_obj_draw_3g_shadows',0