Subversion Repositories Kolibri OS

Rev

Rev 3040 | Rev 3138 | 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
 
2920 IgorA 252
		call combine_colors_0
2230 IgorA 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
2975 IgorA 1075
rot_table: ;таблица для указания на подфункции для поворотов
1076
	dd buf_rotate.8b90,buf_rotate.24b90,buf_rotate.32b90,\
1077
	buf_rotate.8b180,buf_rotate.24b180,buf_rotate.32b180
1078
 
1079
;поворот изображения на 90 или 180 градусов
1080
align 4
1081
proc buf_rotate, buf_struc:dword, angle:dword
1082
locals
1083
	n_data dd ?
1084
	dec_h dd ? ;число байт, для уменьшения координаты y
1085
endl
1086
	pushad
1087
	mov edi,[buf_struc]
1088
	mov ebx,buf2d_w
1089
	mov ecx,buf2d_h
1090
 
1091
	lea eax,[rot_table]
1092
	cmp dword[angle],90 ;проверка угла поворота
1093
	je .beg_0
1094
	cmp dword[angle],180
1095
	jne @f
1096
		add eax,12
1097
		jmp .beg_0
1098
	@@:
1099
	jmp .end_f
1100
	.beg_0: ;проверка битности буфера
1101
	cmp buf2d_bits,8
1102
	jne @f
1103
		jmp dword[eax]
1104
	@@:
1105
	cmp buf2d_bits,24
1106
	jne @f
1107
		add eax,4
1108
		jmp dword[eax]
1109
	@@:
1110
	cmp buf2d_bits,32
1111
	jne @f
1112
		add eax,8
1113
		jmp dword[eax]
1114
	@@:
1115
	jmp .end_f
1116
 
1117
	.8b90: ;поворот 8 битного буфера на 90 градусов
1118
		mov edx,ecx ;edx - buf_h
1119
		imul ecx,ebx
1120
		invoke mem.alloc,ecx ;выделяем временную память
1121
		cmp eax,0
1122
		je .end_f
1123
		mov [n_data],eax
1124
		mov [dec_h],ecx
1125
		inc dword[dec_h]
1126
 
1127
		;copy buf --> mem
1128
		mov edi,[buf_struc]
1129
		mov esi,buf2d_data
1130
		mov edi,eax ;[n_data]
1131
		dec edx ;коректируем edx на 1 байт, для компенсации сдвига в movsb
1132
		add edi,edx
1133
		xor eax,eax
1134
		cld
1135
		.cycle_0:
1136
			movsb
1137
			add edi,edx
1138
			inc eax
1139
			cmp eax,ebx
1140
			jl @f
1141
				xor eax,eax
1142
				sub edi,[dec_h]
1143
			@@:
1144
			loop .cycle_0
1145
 
1146
		;change buf_w <---> buf_h
1147
		mov esi,[n_data]
1148
		mov edi,[buf_struc]
1149
		mov edi,buf2d_data
1150
		mov ecx,ebx
1151
		inc edx ;исправляем скоректированный edx
1152
		imul ecx,edx
1153
		;copy buf <-- mem
1154
		;cld
1155
		rep movsb
1156
		invoke mem.free,[n_data]
1157
		jmp .change_w_h
1158
	.24b90: ;поворот 24 битного буфера на 90 градусов
1159
		mov esi,ecx
1160
		imul esi,ebx
1161
		lea ecx,[ecx+ecx*2]
1162
		mov edx,ecx ;edx - buf_h * 3
1163
		imul ecx,ebx
1164
		invoke mem.alloc,ecx ;выделяем временную память
1165
		cmp eax,0
1166
		je .end_f
1167
		mov [n_data],eax
1168
		mov [dec_h],ecx
1169
		add dword[dec_h],3
1170
 
1171
		;copy buf --> mem
1172
 
1173
		mov edi,[buf_struc]
1174
		mov ecx,esi
1175
		mov esi,buf2d_data
1176
		mov edi,eax ;[n_data]
1177
		sub edx,3 ;коректируем edx на 3 байта, для компенсации сдвига
1178
		add edi,edx
1179
		xor eax,eax
1180
		cld
1181
		.cycle_1:
1182
			movsw
1183
			movsb
1184
			add edi,edx
1185
			inc eax
1186
			cmp eax,ebx
1187
			jl @f
1188
				xor eax,eax
1189
				sub edi,[dec_h]
1190
			@@:
1191
			loop .cycle_1
1192
 
1193
		;copy buf <-- mem
1194
		mov esi,[n_data]
1195
		mov edi,[buf_struc]
1196
		mov edi,buf2d_data
1197
		mov ecx,ebx
1198
		add edx,3 ;исправляем скоректированный edx
1199
		imul ecx,edx
1200
		;cld
1201
		rep movsb
1202
		invoke mem.free,[n_data]
1203
		jmp .change_w_h
1204
	.32b90: ;поворот 32 битного буфера на 90 градусов
1205
		shl ecx,2
1206
		mov edx,ecx ;edx - buf_h * 4
1207
		imul ecx,ebx
1208
		invoke mem.alloc,ecx ;выделяем временную память
1209
		cmp eax,0
1210
		je .end_f
1211
		mov [n_data],eax
1212
		mov [dec_h],ecx
1213
		add dword[dec_h],4
1214
 
1215
		;copy buf --> mem
1216
		mov edi,[buf_struc]
1217
		shr ecx,2
1218
		mov esi,buf2d_data
1219
		mov edi,eax ;[n_data]
1220
		sub edx,4 ;коректируем edx на 4 байта, для компенсации сдвига в movsd
1221
		add edi,edx
1222
		xor eax,eax
1223
		cld
1224
		.cycle_2:
1225
			movsd
1226
			add edi,edx
1227
			inc eax
1228
			cmp eax,ebx
1229
			jl @f
1230
				xor eax,eax
1231
				sub edi,[dec_h]
1232
			@@:
1233
			loop .cycle_2
1234
 
1235
		;copy buf <-- mem
1236
		mov esi,[n_data]
1237
		mov edi,[buf_struc]
1238
		mov edi,buf2d_data
1239
		mov ecx,ebx
1240
		add edx,4 ;исправляем скоректированный edx
1241
		imul ecx,edx
1242
		shr ecx,2
1243
		;cld
1244
		rep movsd
1245
		invoke mem.free,[n_data]
1246
		;jmp .change_w_h
1247
	.change_w_h: ;change buf_w <---> buf_h
1248
		mov edi,[buf_struc]
1249
		mov eax,buf2d_w
1250
		mov ebx,buf2d_h
1251
		mov buf2d_h,eax
1252
		mov buf2d_w,ebx
1253
		jmp .end_f
1254
	.8b180: ;поворот 8 битного буфера на 180 градусов
1255
		mov edi,buf2d_data
1256
		mov esi,edi
1257
		imul ecx,ebx
1258
		add esi,ecx
1259
		dec esi
1260
		shr ecx,1 ;ecx - число пикселей буфера : 2
1261
		std
1262
		@@:
1263
			lodsb
1264
			mov ah,byte[edi]
1265
			mov byte[esi+1],ah
1266
			mov byte[edi],al
1267
			inc edi
1268
			loop @b
1269
			jmp .end_f
1270
	.24b180: ;поворот 24 битного буфера на 180 градусов
1271
		mov esi,buf2d_data
1272
		mov edi,esi
1273
		imul ecx,ebx
1274
		mov eax,ecx
1275
		lea ecx,[ecx+ecx*2]
1276
		add edi,ecx
1277
		sub edi,3
1278
		shr eax,1
1279
		mov ecx,eax ;ecx - число пикселей буфера : 2
1280
		cld
1281
		@@:
1282
			lodsw
1283
			mov edx,eax
1284
			lodsb
1285
			mov bx,word[edi]
1286
			mov word[esi-3],bx
1287
			mov bl,byte[edi+2]
1288
			mov byte[esi-1],bl
1289
			mov byte[edi+2],al
1290
			mov word[edi],dx
1291
			sub edi,3
1292
			loop @b
1293
			jmp .end_f
1294
	.32b180: ;поворот 32 битного буфера на 180 градусов
1295
		mov edi,buf2d_data
1296
		mov esi,edi
1297
		imul ecx,ebx
1298
		shl ecx,2
1299
		add esi,ecx
1300
		sub esi,4
1301
		shr ecx,3 ;ecx - число пикселей буфера : 2
1302
		std
1303
		@@:
1304
			lodsd
1305
			mov ebx,dword[edi]
1306
			mov dword[esi+4],ebx
1307
			mov dword[edi],eax
1308
			add edi,4
1309
			loop @b
1310
		;jmp .end_f
1311
 
1312
	.end_f:
1313
	popad
1314
	ret
1315
endp
1316
 
1317
align 4
1535 IgorA 1318
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1319
locals
1320
	loc_1 dd ?
1321
	loc_2 dd ?
1322
	napravl db ?
1323
endl
1324
	pushad
1325
		mov eax,dword[coord_x1]
1326
		sub eax,dword[coord_x0]
1327
		bt eax,31
1328
		jae @f
1329
			neg eax
1330
			inc eax
1331
		@@:
1332
		mov ebx,dword[coord_y1]
1333
		sub ebx,dword[coord_y0]
2230 IgorA 1334
		jnz @f
1335
			;если задана горизонтальная линия y0=y1
1336
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1337
			jmp .coord_end
1338
		@@:
1535 IgorA 1339
		bt ebx,31
1340
		jae @f
1341
			neg ebx
1342
			inc ebx
1343
		@@:
2230 IgorA 1344
		mov edx,dword[color]
1535 IgorA 1345
 
1346
		mov [napravl],byte 0 ;bool steep=false
1347
		cmp eax,ebx
1348
		jle @f
1349
			mov [napravl],byte 1 ;bool steep=true
1350
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1351
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1352
		@@:
1353
		mov eax,dword[coord_y0] ;x0
1354
		cmp eax,dword[coord_y1] ;if(x0>x1)
1355
		jle @f
1356
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1357
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1358
		@@:
1359
 
1360
; int deltax esi
1361
; int deltay edi
1362
; int error  ebp-6
1363
; int ystep  ebp-8
1364
 
1365
		mov eax,dword[coord_y0]
1366
		mov esi,dword[coord_y1]
1367
		sub esi,eax ;deltax = y1-y0
1368
		mov ebx,esi
1369
		shr ebx,1
1370
		mov [loc_1],ebx ;error = deltax/2
1371
 
1372
		mov eax,dword[coord_x0]
1373
		mov edi,dword[coord_x1]
1374
		mov [loc_2],dword -1 ;ystep = -1
1375
		cmp eax,edi ;if (x0
1376
		jge @f
1377
			mov [loc_2],dword 1 ;ystep = 1
1378
		@@:
1379
		sub edi,eax ;x1-x0
1380
 
1381
		bts edi,31
1382
		jae @f
1383
			neg edi
1384
			inc edi
1385
		@@:
1386
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1387
 
1388
		mov eax,edi
1389
		mov edi,[buf_struc]
2358 IgorA 1390
		cmp buf2d_bits,8
1391
		je @f
1535 IgorA 1392
		cmp buf2d_bits,24
2358 IgorA 1393
		je @f
1394
			jmp .coord_end
1395
		@@:
1535 IgorA 1396
 
1397
		cmp [napravl],0
1398
		jne .coord_yx
1399
			mov ebx,dword[coord_x0]
1400
			mov ecx,dword[coord_y0]
1401
 
1402
			@@: ;for (x=x0 ; x
1403
				cmp ecx,dword[coord_y1]
1404
				jg @f ;jge ???
1405
				call draw_pixel
1406
 
1407
				sub dword[loc_1],eax ;error -= deltay
1408
				cmp dword[loc_1],0 ;if(error<0)
1409
				jge .if0
1410
					add ebx,[loc_2] ;y += ystep
1411
					add [loc_1],esi ;error += deltax
1412
				.if0:
1413
				inc ecx
1414
				jmp @b
1415
			@@:
1416
			jmp .coord_end
1417
		.coord_yx:
1418
			mov ebx,dword[coord_y0]
1419
			mov ecx,dword[coord_x0]
1420
 
1421
			@@: ;for (x=x0 ; x
1422
				cmp ebx,dword[coord_y1]
1423
				jg @f ;jge ???
1424
				call draw_pixel
1425
 
1426
				sub dword[loc_1],eax ;error -= deltay
1427
				cmp dword[loc_1],0 ;if(error<0)
1428
				jge .if1
1429
					add ecx,[loc_2] ;y += ystep
1430
					add [loc_1],esi ;error += deltax
1431
				.if1:
1432
				inc ebx
1433
				jmp @b
1434
			@@:
1435
	.coord_end:
1436
	popad
1437
	ret
1438
endp
1439
 
2230 IgorA 1440
;рисование сглаженной линии
1441
align 4
1442
proc buf_line_brs_sm, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1443
locals
1444
	loc_1 dd ?
1445
	loc_2 dd ?
1446
	napravl db ?
1447
endl
1448
	pushad
1449
		mov eax,dword[coord_x1]
1450
		sub eax,dword[coord_x0]
1451
		bt eax,31
1452
		jae @f
1453
			neg eax
1454
			inc eax
1455
		@@:
1456
		mov ebx,dword[coord_y1]
1457
		sub ebx,dword[coord_y0]
1458
		jnz @f
1459
			;если задана горизонтальная линия y0=y1
1460
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1461
			jmp .coord_end
1462
		@@:
1463
		bt ebx,31
1464
		jae @f
1465
			neg ebx
1466
			inc ebx
1467
		@@:
1468
		mov edx,dword[color]
1469
 
1470
		mov [napravl],byte 0 ;bool steep=false
1471
		cmp eax,ebx
1472
		jle @f
1473
			mov [napravl],byte 1 ;bool steep=true
1474
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1475
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1476
		@@:
1477
		mov eax,dword[coord_y0] ;x0
1478
		cmp eax,dword[coord_y1] ;if(x0>x1)
1479
		jle @f
1480
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1481
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1482
		@@:
1483
 
1484
; int deltax esi
1485
; int deltay edi
1486
; int error  ebp-6
1487
; int ystep  ebp-8
1488
 
1489
		mov eax,dword[coord_y0]
1490
		mov esi,dword[coord_y1]
1491
		sub esi,eax ;deltax = y1-y0
1492
		mov ebx,esi
1493
		shr ebx,1
1494
		mov [loc_1],ebx ;error = deltax/2
1495
 
1496
		mov eax,dword[coord_x0]
1497
		mov edi,dword[coord_x1]
1498
		mov [loc_2],dword -1 ;ystep = -1
1499
		cmp eax,edi ;if (x0
1500
		jge @f
1501
			mov [loc_2],dword 1 ;ystep = 1
1502
		@@:
1503
		sub edi,eax ;x1-x0
1504
 
1505
		bts edi,31
1506
		jae @f
1507
			neg edi
1508
			inc edi
1509
		@@:
1510
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1511
 
1512
		mov eax,edi
1513
		mov edi,[buf_struc]
1514
		cmp buf2d_bits,24
1515
		jne .coord_end
1516
 
1517
		cmp [napravl],0
1518
		jne .coord_yx
1519
			mov ebx,dword[coord_x0]
1520
			mov ecx,dword[coord_y0]
1521
 
1522
			@@: ;for (x=x0 ; x
1523
				cmp ecx,dword[coord_y1]
1524
				jg @f ;jge ???
1525
				push eax
1526
					mov eax,esi
1527
					sub eax,[loc_1]
1528
					stdcall draw_pixel_transp, eax,esi
1529
				pop eax
1530
				add ebx,[loc_2]
1531
				stdcall draw_pixel_transp, [loc_1],esi
1532
				sub ebx,[loc_2]
1533
 
1534
				sub dword[loc_1],eax ;error -= deltay
1535
				cmp dword[loc_1],0 ;if(error<0)
1536
				jge .if0
1537
					add ebx,[loc_2] ;y += ystep
1538
					add [loc_1],esi ;error += deltax
1539
				.if0:
1540
				inc ecx
1541
				jmp @b
1542
			@@:
1543
			jmp .coord_end
1544
		.coord_yx:
1545
			mov ebx,dword[coord_y0]
1546
			mov ecx,dword[coord_x0]
1547
 
1548
			@@: ;for (x=x0 ; x
1549
				cmp ebx,dword[coord_y1]
1550
				jg @f ;jge ???
1551
				push eax
1552
					mov eax,esi
1553
					sub eax,[loc_1]
1554
					stdcall draw_pixel_transp, eax,esi
1555
				pop eax
1556
				add ecx,[loc_2]
1557
				stdcall draw_pixel_transp, [loc_1],esi
1558
				sub ecx,[loc_2]
1559
 
1560
				sub dword[loc_1],eax ;error -= deltay
1561
				cmp dword[loc_1],0 ;if(error<0)
1562
				jge .if1
1563
					add ecx,[loc_2] ;y += ystep
1564
					add [loc_1],esi ;error += deltax
1565
				.if1:
1566
				inc ebx
1567
				jmp @b
1568
			@@:
1569
	.coord_end:
1570
	popad
1571
	ret
1572
endp
1573
 
1653 IgorA 1574
;рисование горизонтальной линии, потому нет параметра coord_y1
1535 IgorA 1575
align 4
1634 IgorA 1576
proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
1577
	pushad
2358 IgorA 1578
	pushfd
1634 IgorA 1579
		mov edi,[buf_struc]
2358 IgorA 1580
		cmp buf2d_bits,8
1581
		je @f
1634 IgorA 1582
		cmp buf2d_bits,24
2358 IgorA 1583
		je @f
1584
			jmp .end24
1585
		@@: ;определение координат линии относительно буфера
1634 IgorA 1586
 
2177 IgorA 1587
		mov ecx,dword[coord_y0]
1588
		bt ecx,31
1589
		jc .end24 ;если координата y0 отрицательная
1590
		cmp ecx,buf2d_h
1591
		jge .end24 ;если координата y0 больше высоты буфера
1592
 
1634 IgorA 1593
		mov ebx,dword[coord_x0]
1594
		mov esi,dword[coord_x1]
1717 IgorA 1595
		cmp ebx,esi
1596
		jle @f
1597
			xchg ebx,esi ;если x0 > x1 то меняем местами x0 и x1
2177 IgorA 1598
		@@:
2185 IgorA 1599
		bt ebx,31
1600
		jae @f
1601
			;если координата x0 отрицательная
1602
			xor ebx,ebx
1603
		@@:
2177 IgorA 1604
		cmp esi,buf2d_w
1605
		jl @f
2185 IgorA 1606
			;если координата x0 больше ширины буфера
2177 IgorA 1607
			mov esi,buf2d_w
2359 IgorA 1608
			dec esi
2177 IgorA 1609
		@@:
2185 IgorA 1610
		cmp ebx,esi
2358 IgorA 1611
		jg .end24 ;если x0 > x1 может возникнуть когда обе координаты x0, x1 находились за одним из пределов буфера
1717 IgorA 1612
 
2358 IgorA 1613
		cmp buf2d_bits,24
1614
		je .beg24
1615
			;рисование в 8 битном буфере
1616
			;в edx вычисляем начало 1-й точки линии в буфере изображения
1617
			mov edx,buf2d_w ;size x
1618
			imul edx,ecx ;size_x*y
1619
			add edx,ebx	 ;size_x*y+x
1620
			add edx,buf2d_data ;ptr+(size_x*y+x)
1621
			mov edi,edx ;теперь можем портить указатель на буфер
1622
 
1623
			mov ecx,esi
1624
			sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
1625
			inc ecx ;что-бы последняя точка линии также отображалась
1626
			mov eax,dword[color] ;будем использовать только значение в al
1627
			cld
1628
			rep stosb ;цикл по оси x от x0 до x1 (включая x1)
1629
			jmp .end24
1630
 
1631
		.beg24: ;рисование в 24 битном буфере
2177 IgorA 1632
		;в eax вычисляем начало 1-й точки линии в буфере изображения
1633
		mov eax,buf2d_w ;size x
1634
		imul eax,ecx ;size_x*y
1635
		add eax,ebx	 ;size_x*y+x
1636
		lea eax,[eax+eax*2] ;(size_x*y+x)*3
1637
		add eax,buf2d_data  ;ptr+(size_x*y+x)*3
1638
 
2185 IgorA 1639
		mov ecx,esi
1640
		sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
2358 IgorA 1641
		inc ecx ;что-бы последняя точка линии также отображалась
2177 IgorA 1642
		mov edx,dword[color]
2185 IgorA 1643
		mov ebx,edx ;координата x0 в ebx уже не нужна
1644
		ror edx,16 ;поворачиваем регистр что бы 3-й байт попал в dl
1645
		cld
2358 IgorA 1646
		@@: ;цикл по оси x от x0 до x1 (включая x1)
2185 IgorA 1647
			mov word[eax],bx ;copy pixel color
1648
			mov byte[eax+2],dl
1649
			add eax,3
1650
			loop @b
1684 IgorA 1651
		.end24:
2358 IgorA 1652
	popfd
1634 IgorA 1653
	popad
1654
	ret
1655
endp
1656
 
1657
align 4
1658
proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1659
pushad
1660
	mov edi,[buf_struc]
2358 IgorA 1661
	cmp buf2d_bits,8
1662
	je @f
1634 IgorA 1663
	cmp buf2d_bits,24
2358 IgorA 1664
	je @f
1665
		jmp .coord_end
1666
	@@:
1634 IgorA 1667
 
1668
		mov eax,[coord_x]
1669
		mov ebx,[coord_y]
1670
		mov ecx,[w]
2358 IgorA 1671
		;cmp ecx,1
1672
		;jl .coord_end
1673
		cmp ecx,0
1674
		je .coord_end
1675
		jg @f
1676
			add eax,ecx
1677
			inc eax
1678
			neg ecx
1679
		@@:
1634 IgorA 1680
		add ecx,eax
1642 IgorA 1681
		dec ecx
1634 IgorA 1682
		mov edx,[h]
2358 IgorA 1683
		;cmp edx,1
1684
		;jl .coord_end
1685
		cmp edx,0
1686
		je .coord_end
1687
		jg @f
1688
			add ebx,edx
1689
			inc ebx
1690
			neg edx
1691
		@@:
1642 IgorA 1692
 
1634 IgorA 1693
		add edx,ebx
1642 IgorA 1694
		dec edx
1634 IgorA 1695
		mov esi,dword[color]
1696
		stdcall buf_line_h, edi, eax, ebx, ecx, esi ;линия -
1697
		stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;линия |
1698
		stdcall buf_line_h, edi, eax, edx, ecx, esi ;линия -
1699
		stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;линия |
1700
	.coord_end:
1701
popad
1702
	ret
1703
endp
1704
 
1705
align 4
1642 IgorA 1706
proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1707
pushad
1708
	mov edi,[buf_struc]
2358 IgorA 1709
	cmp buf2d_bits,8
1710
	je @f
1642 IgorA 1711
	cmp buf2d_bits,24
2358 IgorA 1712
	je @f
1713
		jmp .coord_end
1714
	@@:
1642 IgorA 1715
		mov eax,[coord_x]
1716
		mov ebx,[coord_y]
1717
		mov edx,[w]
2358 IgorA 1718
		cmp edx,0
1719
		je .coord_end ;если высота 0 пикселей
1720
		jg @f ;если высота положительная
1721
			add eax,edx
1722
			inc eax
1723
			neg edx ;ширину делаем положительной
1724
			;inc edx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1725
		@@:
1642 IgorA 1726
		add edx,eax
2358 IgorA 1727
		dec edx
1642 IgorA 1728
		mov ecx,[h]
2358 IgorA 1729
		cmp ecx,0
1730
		je .coord_end ;если высота 0 пикселей
1731
		jg @f ;если высота положительная
1732
			add ebx,ecx ;сдвигаем верхнюю координату прямоугольника
1733
			inc ebx
1734
			neg ecx ;высоту делаем положительной
1735
			;inc ecx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1736
		@@:
1642 IgorA 1737
		mov esi,dword[color]
1738
		cld
1739
		@@:
1740
			stdcall buf_line_h, edi, eax, ebx, edx, esi ;линия -
1741
			inc ebx
1742
			loop @b
1743
	.coord_end:
1744
popad
1745
	ret
1746
endp
1747
 
1748
align 4
1535 IgorA 1749
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
1750
locals
1751
	po_x dd ?
1752
	po_y dd ?
1753
endl
1754
	pushad
1755
	mov edi,dword[buf_struc]
2358 IgorA 1756
	cmp buf2d_bits,8
1757
	je @f
1535 IgorA 1758
	cmp buf2d_bits,24
2358 IgorA 1759
	je @f
1760
		jmp .error
1761
	@@:
1535 IgorA 1762
		mov edx,dword[color]
1763
 
1764
		finit
1765
		fild dword[coord_x]
1766
		fild dword[coord_y]
1767
		fild dword[r]
1768
		fldz ;px=0
1769
		fld st1 ;py=r
1770
 
1771
		fldpi
1772
		fmul st0,st3
1773
		fistp dword[po_x]
1774
		mov esi,dword[po_x] ;esi=pi*r
1775
		shl esi,1 ;esi=2*pi*r
1776
 
1777
		;st0 = py
1778
		;st1 = px
1779
		;st2 = r
1780
		;st3 = y
1781
		;st4 = x
1782
 
1783
		@@:
1784
			;Point(px + x, y - py)
1785
			fld st1 ;st0=px
1786
			fadd st0,st5 ;st0=px+x
1787
			fistp dword[po_x]
1788
			mov ebx,dword[po_x]
1789
			fld st3 ;st0=y
1790
			fsub st0,st1 ;st0=y-py
1791
			fistp dword[po_y]
1792
			mov ecx,dword[po_y]
1793
			call draw_pixel
1794
			;px += py/r
1795
			fld st0 ;st0=py
1796
			fdiv st0,st3 ;st0=py/r
1797
			faddp st2,st0 ;st3+=st0
1798
			;py -= px/r
1799
			fld st1 ;st0=px
1800
			fdiv st0,st3 ;st0=px/r
1801
			fsubp st1,st0 ;st2-=st0
1802
 
1803
			dec esi
1804
			cmp esi,0
1805
			jge @b
1806
		jmp .exit_fun
1807
	.error:
2358 IgorA 1808
		stdcall print_err,sz_buf2d_circle,txt_err_n8_24b
1535 IgorA 1809
	.exit_fun:
1810
 
1811
	popad
1812
	ret
1813
endp
1814
 
1684 IgorA 1815
;функция для заливки области выбранным цветом
1535 IgorA 1816
align 4
1684 IgorA 1817
proc buf_flood_fill, buf_struc:dword, coord_x:dword, coord_y:dword, mode:dword, color_f:dword, color_b:dword
1818
	pushad
1819
		mov edi,[buf_struc]
1820
		cmp buf2d_bits,24
1821
		jne .end24
1822
 
1823
			mov ebx,dword[coord_x]
1824
			mov ecx,dword[coord_y]
1825
			mov edx,dword[color_f]
1826
			mov esi,dword[color_b]
1827
 
1828
			cmp dword[mode],1 ;в зависимости от 'mode' определяем каким алгоритмом будем пользоваться
1829
			je @f
1830
				call buf_flood_fill_recurs_0 ;заливаем до пикселей цвета esi
1831
				jmp .end24
1832
			@@:
1833
				call buf_flood_fill_recurs_1 ;заливаем пиксели имеющие цвет esi
1834
 
1835
		.end24:
1836
	popad
1837
	ret
1838
endp
1839
 
1840
;input:
1841
; ebx = coord_x
1842
; ecx = coord_y
1843
; edx = цвет заливки
1844
; esi = цвет границы, до которой будет ити заливка
1845
; edi = buf_struc
1846
;output:
1847
; eax = портится
1848
align 4
1849
buf_flood_fill_recurs_0:
1850
	call get_pixel_24
1851
	cmp eax,0xffffffff ;if error coords
1852
	je .end_fun
1853
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1854
	je .end_fun
1855
 
1856
		call draw_pixel
1857
 
1858
		dec ebx
1859
		call get_pixel_24
1860
		cmp eax,esi
1861
		je @f
1862
			call buf_flood_fill_recurs_0
1863
		@@:
1864
		inc ebx
1865
 
1866
 
1867
		inc ebx
1868
		call get_pixel_24
1869
		cmp eax,esi
1870
		je @f
1871
			call buf_flood_fill_recurs_0
1872
		@@:
1873
		dec ebx
1874
 
1875
		dec ecx
1876
		call get_pixel_24
1877
		cmp eax,esi
1878
		je @f
1879
			call buf_flood_fill_recurs_0
1880
		@@:
1881
		inc ecx
1882
 
1883
		inc ecx
1884
		call get_pixel_24
1885
		cmp eax,esi
1886
		je @f
1887
			call buf_flood_fill_recurs_0
1888
		@@:
1889
		dec ecx
1890
 
1891
	.end_fun:
1892
	ret
1893
 
1894
;input:
1895
; ebx = coord_x
1896
; ecx = coord_y
1897
; edx = цвет заливки
1898
; esi = цвет пикселей, по которым будет ити заливка
1899
; edi = buf_struc
1900
;output:
1901
; eax = портится
1902
align 4
1903
buf_flood_fill_recurs_1:
1904
	call get_pixel_24
1905
	cmp eax,0xffffffff ;if error coords
1906
	je .end_fun
1907
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1908
	je .end_fun
1909
	cmp eax,esi ;если цвет пикселя не совпал с заливаемым цветом заливки, то прекращаем заливку
1910
	jne .end_fun
1911
 
1912
		call draw_pixel
1913
 
1914
		dec ebx
1915
		call get_pixel_24
1916
		cmp eax,esi
1917
		jne @f
1918
			call buf_flood_fill_recurs_1
1919
		@@:
1920
		inc ebx
1921
 
1922
 
1923
		inc ebx
1924
		call get_pixel_24
1925
		cmp eax,esi
1926
		jne @f
1927
			call buf_flood_fill_recurs_1
1928
		@@:
1929
		dec ebx
1930
 
1931
		dec ecx
1932
		call get_pixel_24
1933
		cmp eax,esi
1934
		jne @f
1935
			call buf_flood_fill_recurs_1
1936
		@@:
1937
		inc ecx
1938
 
1939
		inc ecx
1940
		call get_pixel_24
1941
		cmp eax,esi
1942
		jne @f
1943
			call buf_flood_fill_recurs_1
1944
		@@:
1945
		dec ecx
1946
 
1947
	.end_fun:
1948
	ret
1949
 
1910 IgorA 1950
;функция для рисования точки
1684 IgorA 1951
align 4
2658 IgorA 1952
proc buf_set_pixel uses ebx ecx edx edi, buf_struc:dword, coord_x:dword, coord_y:dword, color:dword
1953
	mov edi,dword[buf_struc]
1954
	mov ebx,dword[coord_x]
1955
	mov ecx,dword[coord_y]
1956
	mov edx,dword[color]
1957
	call draw_pixel
1910 IgorA 1958
	ret
1959
endp
1960
 
2658 IgorA 1961
;output:
1962
; eax = цвет точки
1963
; в случае ошибки eax = 0xffffffff
1910 IgorA 1964
align 4
2658 IgorA 1965
proc buf_get_pixel uses ebx ecx edi, buf_struc:dword, coord_x:dword, coord_y:dword
1966
	mov edi,dword[buf_struc]
1967
	mov ebx,[coord_x]
1968
	mov ecx,[coord_y]
1969
 
1970
	cmp buf2d_bits,8
1971
	jne @f
1972
		call get_pixel_8
1973
		jmp .end_fun
1974
	@@:
1975
	cmp buf2d_bits,24
1976
	jne @f
1977
		call get_pixel_24
1978
		jmp .end_fun
1979
	@@:
1980
	cmp buf2d_bits,32
1981
	jne @f
1982
		call get_pixel_32
1983
		;jmp .end_fun
1984
	@@:
1985
	.end_fun:
1986
	ret
1987
endp
1988
 
3040 IgorA 1989
;отразить по вертикали (верх и низ меняются местами)
2658 IgorA 1990
align 4
3040 IgorA 1991
proc buf_flip_v, buf_struc:dword
1992
locals
1993
    line_pix dd ? ;кол. пикселей в линии буфера
1994
    line_2byte dd ? ;кол. байт в линии буфера * 2
1995
endl
1996
	pushad
1997
	mov edi,[buf_struc]
1998
    cmp buf2d_bits,24
1999
    jne .end_24
2000
        mov edx,buf2d_w
2001
        mov [line_pix],edx
2002
        mov ebx,buf2d_h
2003
        lea edx,[edx+edx*2]
2004
        mov esi,edx
2005
        imul esi,ebx
2006
        sub esi,edx
2007
        add esi,buf2d_data ;указатель на нижнюю линию
2008
        shr ebx,1 ;кол. линейных циклов
2009
        shl edx,1
2010
        mov [line_2byte],edx
2011
        mov edi,buf2d_data
2012
        xchg edi,esi
2013
        cld
2014
        .flip_24:
2015
        cmp ebx,0
2016
        jle .end_24
2017
        mov ecx,[line_pix]
2018
        @@:
2019
            lodsw
2020
            mov dx,word[edi]
2021
            mov word[esi-2],dx
2022
            mov [edi],ax
2023
            lodsb
2024
            mov ah,byte[edi+2]
2025
            mov byte[esi-1],ah
2026
            mov [edi+2],al
2027
            add edi,3
2028
            loop @b
2029
        sub edi,[line_2byte]
2030
        dec ebx
2031
        jmp .flip_24
2032
    .end_24:
2033
    popad
2034
    ret
2035
endp
2036
 
2037
align 4
1535 IgorA 2038
proc buf_img_wdiv2, buf_struc:dword
2039
	pushad
2040
	mov edi,dword[buf_struc]
2927 IgorA 2041
	cmp buf2d_bits,8
2042
	jne @f
2043
		mov eax,buf2d_w
2044
		mov ecx,buf2d_h
2045
		imul ecx,eax
2046
		stdcall img_8b_wdiv2, buf2d_data,ecx
2047
	@@:
1535 IgorA 2048
	cmp buf2d_bits,24
2927 IgorA 2049
	jne @f
1535 IgorA 2050
		mov eax,buf2d_w
2051
		mov ecx,buf2d_h
2052
		imul ecx,eax
2053
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
2927 IgorA 2054
	@@:
2920 IgorA 2055
	cmp buf2d_bits,32
2927 IgorA 2056
	jne @f
2920 IgorA 2057
		mov eax,buf2d_w
2058
		mov ecx,buf2d_h
2059
		imul ecx,eax
2927 IgorA 2060
		stdcall img_rgba32_wdiv2, buf2d_data,ecx
2061
	@@:
1535 IgorA 2062
	popad
2063
	ret
2064
endp
2065
 
2066
;input:
2927 IgorA 2067
;data_8b - pointer to rgb data
2068
;size - count img pixels (size img data / 3(rgb) )
2069
align 4
2070
proc img_8b_wdiv2 data_8b:dword, size:dword
2071
	mov eax,dword[data_8b]
2072
	mov ecx,dword[size] ;ecx = size
2073
	cld
2074
	@@: ;затемнение цвета пикселей
2075
		shr byte[eax],1
2076
		inc eax
2077
		loop @b
2078
 
2079
	mov eax,dword[data_8b]
2080
	mov ecx,dword[size] ;ecx = size
2081
	shr ecx,1
2082
	@@: ;сложение цветов пикселей
2083
		mov bl,byte[eax+1] ;копируем цвет соседнего пикселя
2084
		add byte[eax],bl
2085
		add eax,2
2086
		loop @b
2087
 
2088
	mov eax,dword[data_8b]
2089
	inc eax
2090
	mov ebx,eax
2091
	inc ebx
2092
	mov ecx,dword[size] ;ecx = size
2093
	shr ecx,1
2094
	dec ecx ;лишний пиксель
2095
	@@: ;поджатие пикселей
2096
		mov dl,byte[ebx]
2097
		mov byte[eax],dl
2098
 
2099
		inc eax
2100
		add ebx,2
2101
		loop @b
2102
	ret
2103
endp
2104
 
2105
;input:
1535 IgorA 2106
;data_rgb - pointer to rgb data
2107
;size - count img pixels (size img data / 3(rgb) )
2108
align 4
2109
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
2110
  mov eax,dword[data_rgb]
2111
  mov ecx,dword[size] ;ecx = size
2112
  lea ecx,[ecx+ecx*2]
2113
  cld
2114
  @@: ;затемнение цвета пикселей
1538 IgorA 2115
		shr byte[eax],1
2116
		inc eax
2117
		loop @b
1535 IgorA 2118
 
2119
  mov eax,dword[data_rgb]
2120
  mov ecx,dword[size] ;ecx = size
2121
  shr ecx,1
2122
  @@: ;сложение цветов пикселей
1538 IgorA 2123
		mov bx,word[eax+3] ;копируем цвет соседнего пикселя
2124
		add word[eax],bx
2125
		mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
2126
		add byte[eax+2],bl
2127
		add eax,6 ;=2*3
2128
		loop @b
1535 IgorA 2129
 
2130
  mov eax,dword[data_rgb]
2131
  add eax,3
2132
  mov ebx,eax
2133
  add ebx,3
2134
  mov ecx,dword[size] ;ecx = size
2135
  shr ecx,1
2136
  dec ecx ;лишний пиксель
2137
  @@: ;поджатие пикселей
1538 IgorA 2138
		mov edx,dword[ebx]
2139
		mov word[eax],dx
2140
		shr edx,16
2141
		mov byte[eax+2],dl
1535 IgorA 2142
 
1538 IgorA 2143
		add eax,3
2144
		add ebx,6
2145
		loop @b
1535 IgorA 2146
  ret
2147
endp
2148
 
2920 IgorA 2149
;input:
2927 IgorA 2150
;data_rgba - pointer to rgba data
2151
;size - count img pixels (size img data / 4(rgba) )
1535 IgorA 2152
align 4
2927 IgorA 2153
proc img_rgba32_wdiv2 data_rgba:dword, size:dword
2154
	mov eax,dword[data_rgba]
2920 IgorA 2155
 
2927 IgorA 2156
	mov eax,dword[data_rgba]
2920 IgorA 2157
	mov ebx,eax
2158
	add ebx,4
2159
	mov ecx,dword[size] ;ecx = size
2160
	shr ecx,1
2161
	@@: ;смешивание цветов пикселей
2162
		call combine_colors_1
2163
		mov [eax],edx
2164
		add eax,8 ;=2*4
2165
		add ebx,8
2166
		loop @b
2167
 
2927 IgorA 2168
	mov eax,dword[data_rgba]
2920 IgorA 2169
	add eax,4
2170
	mov ebx,eax
2171
	add ebx,4
2172
	mov ecx,dword[size] ;ecx = size
2173
	shr ecx,1
2174
	dec ecx ;лишний пиксель
2175
	@@: ;поджатие пикселей
2176
		mov edx,dword[ebx]
2177
		mov dword[eax],edx
2178
 
2179
		add eax,4
2180
		add ebx,8
2181
		loop @b
2182
	ret
2183
endp
2184
 
3040 IgorA 2185
;description:
2186
; сжатие изображения по высоте (высота буфера не меняется)
2920 IgorA 2187
align 4
1535 IgorA 2188
proc buf_img_hdiv2, buf_struc:dword
2189
	pushad
2190
	mov edi,dword[buf_struc]
2927 IgorA 2191
	cmp buf2d_bits,8
2192
	jne @f
2193
		mov eax,buf2d_w
2194
		mov ecx,buf2d_h
2195
		imul ecx,eax
2196
		stdcall img_8b_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2197
		jmp .end_f ;edi портится в функции, потому использование buf2d_bits опасно
2927 IgorA 2198
	@@:
1535 IgorA 2199
	cmp buf2d_bits,24
2927 IgorA 2200
	jne @f
1535 IgorA 2201
		mov eax,buf2d_w
2202
		mov ecx,buf2d_h
2203
		imul ecx,eax
2204
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2205
		jmp .end_f
2927 IgorA 2206
	@@:
2920 IgorA 2207
	cmp buf2d_bits,32
2927 IgorA 2208
	jne @f
2920 IgorA 2209
		mov eax,buf2d_w
2210
		mov ecx,buf2d_h
2211
		imul ecx,eax
2212
		shl eax,2
2927 IgorA 2213
		stdcall img_rgba32_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2214
		;jmp .end_f
2927 IgorA 2215
	@@:
3040 IgorA 2216
	.end_f:
1535 IgorA 2217
	popad
2218
	ret
2219
endp
2220
 
2221
;input:
2927 IgorA 2222
;data_8b - pointer to 8 bit data
2223
;size - count img pixels (size img data)
2224
;size_w - width img in pixels
2225
align 4
2226
proc img_8b_hdiv2, data_8b:dword, size:dword, size_w:dword
2227
 
2228
	mov eax,dword[data_8b] ;eax =
2229
	mov ecx,dword[size]
2230
	cld
2231
	@@: ;затемнение цвета пикселей
2232
		shr byte[eax],1
2233
		inc eax
2234
		loop @b
2235
 
2236
	mov eax,dword[data_8b] ;eax =
2237
	mov esi,dword[size_w]
2238
	mov ebx,esi
2239
	add ebx,eax
2240
	mov ecx,dword[size]  ;ecx = size
2241
	shr ecx,1
2242
	xor edi,edi
2243
	@@: ;сложение цветов пикселей
2244
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
2245
		add byte[eax],dl
2246
 
2247
		inc eax
2248
		inc ebx
2249
		inc edi
2250
		cmp edi,dword[size_w]
2251
		jl .old_line
2252
			add eax,esi
2253
			add ebx,esi
2254
			xor edi,edi
2255
		.old_line:
2256
		loop @b
2257
 
2258
 
2259
	mov eax,dword[data_8b] ;eax =
2260
	add eax,esi ;esi = width*3(rgb)
2261
	mov ebx,eax
2262
	add ebx,esi
2263
	mov ecx,dword[size] ;ecx = size
2264
	shr ecx,1
2265
	sub ecx,dword[size_w] ;лишняя строка пикселей
2266
	xor edi,edi
2267
	@@: ;поджатие пикселей
2268
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
2269
		mov byte[eax],dl
2270
 
2271
		inc eax
2272
		inc ebx
2273
		inc edi
2274
		cmp edi,dword[size_w]
2275
		jl .old_line_2
2276
			add ebx,esi
2277
			xor edi,edi
2278
		.old_line_2:
2279
		loop @b
2280
 
2281
	ret
2282
endp
2283
 
2284
;input:
1535 IgorA 2285
;data_rgb - pointer to rgb data
2286
;size - count img pixels (size img data / 3(rgb) )
2287
;size_w - width img in pixels
2288
align 4
2289
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
2290
 
2291
  mov eax,dword[data_rgb] ;eax =
2292
  mov ecx,dword[size]	  ;ecx = size
2293
  lea ecx,[ecx+ecx*2]
2294
  cld
2295
  @@: ;затемнение цвета пикселей
2296
    shr byte[eax],1
2297
    inc eax
2298
    loop @b
2299
 
2300
  mov eax,dword[data_rgb] ;eax =
2920 IgorA 2301
  mov esi,dword[size_w]
2302
  lea esi,[esi+esi*2] ;esi = width*3(rgb)
1535 IgorA 2303
  mov ebx,esi
2304
  add ebx,eax
2305
  mov ecx,dword[size]  ;ecx = size
2306
  shr ecx,1
2307
  xor edi,edi
2308
  @@: ;сложение цветов пикселей
2309
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
2310
    add word[eax],dx
2311
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
2312
    add byte[eax+2],dl
2313
 
2314
    add eax,3
2315
    add ebx,3
2316
    inc edi
2317
    cmp edi,dword[size_w]
2318
    jl .old_line
2319
      add eax,esi
2320
      add ebx,esi
2321
      xor edi,edi
2322
    .old_line:
2323
    loop @b
2324
 
2325
 
2326
  mov eax,dword[data_rgb] ;eax =
2327
  add eax,esi ;esi = width*3(rgb)
2920 IgorA 2328
  mov ebx,eax
2329
  add ebx,esi
1535 IgorA 2330
  mov ecx,dword[size] ;ecx = size
2331
  shr ecx,1
2332
  sub ecx,dword[size_w] ;лишняя строка пикселей
2333
  xor edi,edi
2334
  @@: ;поджатие пикселей
2335
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
2336
    mov word[eax],dx
2337
    shr edx,16
2338
    mov byte[eax+2],dl
2339
 
2340
    add eax,3
2341
    add ebx,3
2342
    inc edi
2343
    cmp edi,dword[size_w]
2344
    jl .old_line_2
2345
      add ebx,esi
2346
      xor edi,edi
2347
    .old_line_2:
2348
    loop @b
2349
 
2350
  ret
2351
endp
2352
 
2920 IgorA 2353
;input:
2927 IgorA 2354
;data_rgba - pointer to rgba data
2355
;size - count img pixels (size img data / 4(rgba) )
2920 IgorA 2356
;size_w_b - width img in bytes
2357
align 4
2927 IgorA 2358
proc img_rgba32_hdiv2, data_rgba:dword, size:dword, size_w_b:dword
2920 IgorA 2359
 
2927 IgorA 2360
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 2361
	mov ebx,dword[size_w_b]
2362
	add ebx,eax
2363
	mov ecx,dword[size]  ;ecx = size
2364
	shr ecx,1
2365
	xor edi,edi
2366
	@@: ;смешивание цветов пикселей
2367
		call combine_colors_1
2368
		mov dword[eax],edx
2369
 
2370
		add eax,4
2371
		add ebx,4
2372
		add edi,4
2373
		cmp edi,dword[size_w_b]
2374
		jl .old_line
2375
			add eax,dword[size_w_b]
2376
			add ebx,dword[size_w_b]
2377
			xor edi,edi
2378
		.old_line:
2379
		loop @b
2380
 
2381
 
2927 IgorA 2382
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 2383
	mov ebx,dword[size_w_b]
2384
	add eax,ebx
2385
	add ebx,eax
2386
	mov ecx,dword[size] ;ecx = size
2387
	shl ecx,1
2388
	sub ecx,dword[size_w_b] ;лишняя строка пикселей
2389
	shr ecx,2
2390
	xor edi,edi
2391
	@@: ;поджатие пикселей
2392
		mov edx,dword[ebx] ;копируем цвет нижнего пикселя
2393
		mov dword[eax],edx
2394
 
2395
		add eax,4
2396
		add ebx,4
2397
		add edi,4
2398
		cmp edi,dword[size_w_b]
2399
		jl .old_line_2
2400
			add ebx,dword[size_w_b]
2401
			xor edi,edi
2402
		.old_line_2:
2403
		loop @b
2404
 
2405
	ret
2406
endp
2407
 
2408
;input:
2409
; eax - указатель на 32-битный цвет
2410
; ebx - указатель на 32-битный цвет
2411
;output:
2412
; edx - 32-битный цвет смешанный с учетом прозрачности
2413
;destroy:
2414
; esi
2415
align 4
2416
proc combine_colors_1 uses ecx edi
2417
locals
2418
	c_blye dd ?
2419
	c_green dd ?
2420
	c_red dd ?
2421
endl
2422
	movzx edi,byte[eax+3]
2423
	cmp edi,255
2424
	je .c0z
2425
	movzx esi,byte[ebx+3]
2426
	cmp esi,255
2427
	je .c1z
2927 IgorA 2428
	cmp edi,esi
2429
	je .c0_c1
2920 IgorA 2430
 
2431
	;переворачиваем значения прозрачностей
2432
	neg edi
2433
	inc edi
2434
	add edi,255
2435
	neg esi
2436
	inc esi
2437
	add esi,255
2438
 
2439
	movzx ecx,byte[eax]
2440
	imul ecx,edi
2441
	mov [c_blye],ecx
2442
	movzx ecx,byte[ebx]
2443
	imul ecx,esi
2444
	add [c_blye],ecx
2445
 
2446
	movzx ecx,byte[eax+1]
2447
	imul ecx,edi
2448
	mov [c_green],ecx
2449
	movzx ecx,byte[ebx+1]
2450
	imul ecx,esi
2451
	add [c_green],ecx
2452
 
2453
	movzx ecx,byte[eax+2]
2454
	imul ecx,edi
2455
	mov [c_red],ecx
2456
	movzx ecx,byte[ebx+2]
2457
	imul ecx,esi
2458
	add [c_red],ecx
2459
 
2460
push eax ebx
2461
	xor ebx,ebx
2462
	mov eax,[c_red]
2463
	xor edx,edx
2464
	mov ecx,edi
2465
	add ecx,esi
2466
	div ecx
2467
	mov bl,al
2468
	shl ebx,16
2469
	mov eax,[c_green]
2470
	xor edx,edx
2471
	div ecx
2472
	mov bh,al
2473
	mov eax,[c_blye]
2474
	xor edx,edx
2475
	div ecx
2476
	mov bl,al
2477
 
2478
	shr ecx,1
2479
	;переворачиваем значения прозрачности
2480
	neg ecx
2481
	inc ecx
2482
	add ecx,255
2483
 
2484
	shl ecx,24
2485
	add ebx,ecx
2486
	mov edx,ebx
2487
pop ebx eax
2488
 
2489
	jmp .end_f
2927 IgorA 2490
	.c0_c1: ;если прозрачности обоих цветов совпадают
2491
		mov edx,dword[eax]
2492
		shr edx,1
2493
		and edx,011111110111111101111111b
2494
		mov esi,dword[ebx]
2495
		shr esi,1
2496
		and esi,011111110111111101111111b
2497
		add edx,esi
2498
		ror edi,8 ;перемещаем значение прозрачности в старший байт edi
2499
		or edx,edi
2500
		jmp .end_f
2920 IgorA 2501
	.c0z: ;если цвет в eax прозрачный
2502
		mov edx,dword[ebx]
2503
		movzx edi,byte[ebx+3]
2504
		jmp @f
2505
	.c1z: ;если цвет в ebx прозрачный
2506
		mov edx,dword[eax]
2507
	@@:
2508
		add edi,255 ;делаем цвет на половину прозрачным
2509
		shr edi,1
2510
		cmp edi,255
2511
		jl @f
2512
			mov edi,255 ;максимальная прозрачность не более 255
2513
		@@:
2514
		shl edi,24
2515
		and edx,0xffffff ;снимаем старую прозрачность
2516
		add edx,edi
2517
	.end_f:
2518
	ret
2519
endp
2520
 
1535 IgorA 2521
;преобразование буфера из 24-битного в 8-битный
2522
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
2523
align 4
2524
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
2525
	pushad
2526
	mov edi,dword[buf_struc]
2527
	cmp buf2d_bits,24
2528
	jne .error
2529
		mov eax,buf2d_w
2530
		mov ecx,buf2d_h
2531
		imul ecx,eax
2532
		mov esi,ecx
2533
		;ebx - память из которой копируется
2534
		;edx - память куда копируется
2535
		mov edx,buf2d_data
2536
		mov ebx,edx
2537
		cmp [spectr],3
2538
		jge @f
2539
			add ebx,[spectr]
2540
		@@:
2541
			mov al,byte[ebx]
2542
			mov byte[edx],al
2543
			add ebx,3
2544
			inc edx
2545
			loop @b
2546
		mov buf2d_bits,8
2547
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
2548
		jmp .end_conv
2549
	.error:
2550
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
2551
	.end_conv:
2552
	popad
2553
	ret
2554
endp
2555
 
2556
;преобразование буфера из 24-битного в 32-битный
2557
align 4
2558
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
2559
	pushad
2560
	mov edi,dword[buf_struc]
2561
	cmp buf2d_bits,24
2562
	jne .error1
2563
		mov ecx,buf2d_w
2564
		mov ebx,buf2d_h
2565
		imul ebx,ecx
2566
		mov ecx,ebx ;ecx = size  8 b
2567
		shl ebx,2   ;ebx = size 32 b
2568
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
2569
		mov buf2d_data,eax ;на случай если изменился указатель на данные
2570
		mov buf2d_bits,32
2571
		mov edx,ebx ;edx = size 32 b
2572
		sub ebx,ecx ;ebx = size 24 b
2573
		mov eax,ecx
2574
		;eax - размер  8 битных данных
2575
		;ebx - размер 24 битных данных
2576
		;edx - размер 32 битных данных
2577
		add ebx,buf2d_data
2578
		add edx,buf2d_data
2579
		mov edi,dword[buf_str8]
2580
		cmp buf2d_bits,8
2581
		jne .error2
2582
		add eax,buf2d_data
2583
		mov edi,edx
2584
		;eax - указатель на конец  8 битных данных
2585
		;ebx - указатель на конец 24 битных данных
2586
		;edi - указатель на конец 32 битных данных
2587
		@@:
2588
			sub edi,4 ;отнимаем в начале цикла,
2589
			sub ebx,3 ; потому, что указатели стоят
2590
			dec eax   ; за пределами буферов
2591
			mov edx,dword[ebx]
2592
			mov dword[edi],edx
2593
			mov dl,byte[eax]
2594
			mov byte[edi+3],dl
2595
			loop @b
2596
 
2597
		jmp .end_conv
2598
	.error1:
2599
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
2600
		jmp .end_conv
2601
	.error2:
2602
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
2603
	.end_conv:
2604
	popad
2605
	ret
2606
endp
2607
 
2608
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
2609
; указываются координаты вставки буфера buf_source относительно buf_destination
2610
; прозрачность при копировании не учитывается
2611
align 4
2612
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2613
	locals
2614
		right_bytes dd ?
2615
	endl
2616
	pushad
2617
 
2618
	mov edi,[buf_source]
2619
	cmp buf2d_bits,24
2620
	je .sou24
2621
	cmp buf2d_bits,32
2622
	je .sou32
2623
		jmp .copy_end ;формат буфера не поодерживается
2624
 
1648 IgorA 2625
	.sou24: ;в источнике 24 битная картинка
1535 IgorA 2626
	mov eax,buf2d_w
2627
	mov edx,buf2d_h ;высота копируемой картинки
2628
	mov esi,buf2d_data ;данные копируемой картинки
2629
 
2630
	mov edi,[buf_destination]
2631
	cmp buf2d_bits,24
2632
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2633
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2634
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2635
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2636
		mov ebx,buf2d_h ;ebx - высота основного буфера
2637
		mov ecx,[coord_y]
2422 IgorA 2638
		cmp ecx,0
2639
		jge @f
2640
			;если координата coord_y<0 (1-я настройка)
2641
			add edx,ecx ;уменьшаем высоту копируемой картинки
2642
			cmp edx,0
2643
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2644
			neg ecx
2645
			;inc ecx
2646
			imul ecx,eax
2647
			lea ecx,[ecx+ecx*2] ;по 3 байта на пиксель
2648
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2649
			xor ecx,ecx ;обнуляем координату coord_y
2650
		@@:
1535 IgorA 2651
		cmp ecx,ebx
2652
		jge .copy_end ;если координата 'y' больше высоты буфера
2653
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2654
		cmp ecx,ebx
2655
		jle @f
2656
			sub ecx,ebx
2657
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2658
		@@:
2659
		mov ebx,buf2d_w
2422 IgorA 2660
		mov ecx,[coord_y] ;ecx используем для временных целей
2661
		cmp ecx,0
2662
		jg .end_otr_c_y_24
2663
			;если координата coord_y<=0 (2-я настройка)
2664
			mov ecx,[coord_x]
2665
			jmp @f
2666
		.end_otr_c_y_24:
2667
		imul ecx,ebx
1535 IgorA 2668
		add ecx,[coord_x]
2422 IgorA 2669
		@@:
1535 IgorA 2670
		lea ecx,[ecx+ecx*2]
2671
		add ecx,buf2d_data
2672
		sub ebx,eax
2673
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2674
 
2675
	mov [right_bytes],0
2676
	mov ecx,[coord_x]
2677
	cmp ecx,ebx
2678
	jl @f
2679
		sub ecx,ebx
2680
		sub eax,ecx ;укорачиваем копируемую строку
2681
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2682
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2683
		mov [right_bytes],ecx
2684
	@@:
2685
 
2686
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
2687
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2688
 
2689
	cld
2690
	cmp [right_bytes],0
2691
	jg .copy_1
2692
	.copy_0: ;простое копирование
2693
		mov ecx,eax
2694
		rep movsb
2695
		add edi,ebx
2696
		dec edx
2697
		cmp edx,0
2698
		jg .copy_0
2699
	jmp .copy_end
2700
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2701
		mov ecx,eax
2702
		rep movsb
2703
		add edi,ebx
2704
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2705
		dec edx
2706
		cmp edx,0
2707
		jg .copy_1
2708
	jmp .copy_end
2709
 
2710
	.sou32: ;в источнике 32 битная картинка
2711
	mov eax,buf2d_w
2712
	mov edx,buf2d_h ;высота копируемой картинки
2713
	mov esi,buf2d_data ;данные копируемой картинки
2714
 
2715
	mov edi,[buf_destination]
2716
	cmp buf2d_bits,24
2717
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2718
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2719
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2720
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2721
		mov ebx,buf2d_h ;ebx - высота основного буфера
2722
		mov ecx,[coord_y]
2422 IgorA 2723
		cmp ecx,0
2724
		jge @f
2725
			;если координата coord_y<0 (1-я настройка)
2726
			add edx,ecx ;уменьшаем высоту копируемой картинки
2727
			cmp edx,0
2728
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2729
			neg ecx
2730
			;inc ecx
2731
			imul ecx,eax
2732
			shl ecx,2 ;по 4 байта на пиксель
2733
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2734
			xor ecx,ecx ;обнуляем координату coord_y
2735
		@@:
1535 IgorA 2736
		cmp ecx,ebx
2737
		jge .copy_end ;если координата 'y' больше высоты буфера
2738
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2739
		cmp ecx,ebx
2740
		jle @f
2741
			sub ecx,ebx
2742
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2743
		@@:
2744
		mov ebx,buf2d_w
2422 IgorA 2745
		;mov ecx,ebx ;ecx используем для временных целей
2746
		;imul ecx,[coord_y]
2747
		;add ecx,[coord_x]
2748
		mov ecx,[coord_y] ;ecx используем для временных целей
2749
		cmp ecx,0
2750
		jg .end_otr_c_y_32
2751
			;если координата coord_y<=0 (2-я настройка)
2752
			mov ecx,[coord_x]
2753
			jmp @f
2754
		.end_otr_c_y_32:
2755
		imul ecx,ebx
1535 IgorA 2756
		add ecx,[coord_x]
2422 IgorA 2757
		@@:
1535 IgorA 2758
		lea ecx,[ecx+ecx*2]
2759
		add ecx,buf2d_data
2760
		sub ebx,eax
2761
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2762
 
2763
	mov [right_bytes],0
2764
	mov ecx,[coord_x]
2765
	cmp ecx,ebx
2766
	jl @f
2767
		sub ecx,ebx
2768
		sub eax,ecx ;укорачиваем копируемую строку
2769
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2770
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2771
		mov [right_bytes],ecx
2772
	@@:
2773
 
2774
	;eax - колличество пикселей в 1-й строке копируемой картинки
2775
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2776
 
2777
	cld
2778
	cmp [right_bytes],0
2779
	jg .copy_3
2780
	.copy_2: ;простое копирование
2781
		mov ecx,eax
2782
		@@:
2783
			movsw
2784
			movsb
2785
			inc esi
2786
			loop @b
2787
		add edi,ebx
2788
		dec edx
2789
		cmp edx,0
2790
		jg .copy_2
2791
	jmp .copy_end
2792
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
2793
		mov ecx,eax
2794
		@@:
2795
			movsw
2796
			movsb
2797
			inc esi
2798
			loop @b
2799
		add edi,ebx
2800
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2801
		dec edx
2802
		cmp edx,0
2803
		jg .copy_3
2804
 
2805
	.copy_end:
2806
	popad
2807
	ret
2808
endp
2809
 
2810
;input:
2811
; esi = pointer to color1 + transparent
2812
; edi = pointer to background color2
2813
;output:
2814
; [edi] = combine color
2815
align 4
2920 IgorA 2816
combine_colors_0:
1535 IgorA 2817
	push ax bx cx dx
2818
	mov bx,0x00ff ;---get transparent---
2748 IgorA 2819
	movzx cx,byte[esi+3] ;pro
1535 IgorA 2820
	sub bx,cx ;256-pro
1653 IgorA 2821
	;---blye---
2748 IgorA 2822
	movzx ax,byte[esi]
1535 IgorA 2823
	imul ax,bx
2748 IgorA 2824
	movzx dx,byte[edi]
1535 IgorA 2825
	imul dx,cx
2826
	add ax,dx
1653 IgorA 2827
	mov byte[edi],ah
1535 IgorA 2828
	;---green---
2748 IgorA 2829
	movzx ax,byte[esi+1]
1535 IgorA 2830
	imul ax,bx
2748 IgorA 2831
	movzx dx,byte[edi+1]
1535 IgorA 2832
	imul dx,cx
2833
	add ax,dx
2834
	mov byte[edi+1],ah
1653 IgorA 2835
	;---red---
2748 IgorA 2836
	movzx ax,byte[esi+2]
1535 IgorA 2837
	imul ax,bx
2748 IgorA 2838
	movzx dx,byte[edi+2]
1535 IgorA 2839
	imul dx,cx
2840
	add ax,dx
1653 IgorA 2841
	mov byte[edi+2],ah
1535 IgorA 2842
 
2843
	pop dx cx bx ax
2844
	ret
2845
 
2846
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
2847
; указываются координаты вставки буфера buf_source относительно buf_destination
2848
; при копировании учитывается прозрачность
2849
align 4
2850
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2851
	locals
2927 IgorA 2852
		lost_bytes dd ?
1535 IgorA 2853
	endl
2854
	pushad
2855
 
2856
	mov edi,[buf_source]
2857
	cmp buf2d_bits,32
2858
	jne .copy_end ;формат буфера не поодерживается
2859
	mov eax,buf2d_w
2860
	mov edx,buf2d_h ;высота копируемой картинки
2861
	mov esi,buf2d_data ;данные копируемой картинки
2862
 
2863
	mov edi,[buf_destination]
2864
	cmp buf2d_bits,24
2865
	jne .copy_end ;формат буфера не поодерживается
2866
		mov ebx,buf2d_h ;ebx - высота основного буфера
2867
		mov ecx,[coord_y]
2383 IgorA 2868
		cmp ecx,0
2869
		jge @f
2870
			;если координата coord_y<0 (1-я настройка)
2871
			add edx,ecx ;уменьшаем высоту копируемой картинки
2872
			cmp edx,0
2873
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2874
			neg ecx
2875
			;inc ecx
2876
			imul ecx,eax
2422 IgorA 2877
			shl ecx,2 ;по 4 байта на пиксель
2383 IgorA 2878
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2879
			xor ecx,ecx ;обнуляем координату coord_y
2880
		@@:
1535 IgorA 2881
		cmp ecx,ebx
2882
		jge .copy_end ;если координата 'y' больше высоты буфера
2883
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2884
		cmp ecx,ebx
2885
		jle @f
2886
			sub ecx,ebx
2887
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2888
		@@:
2889
		mov ebx,buf2d_w
2890
		mov ecx,ebx ;ecx используем для временных целей
2383 IgorA 2891
		cmp [coord_y],0
2892
		jg .end_otr_c_y
2893
			;если координата coord_y<=0 (2-я настройка)
2894
			mov ecx,[coord_x]
2895
			jmp @f
2896
		.end_otr_c_y:
1535 IgorA 2897
		imul ecx,[coord_y]
2898
		add ecx,[coord_x]
2383 IgorA 2899
		@@:
1535 IgorA 2900
		lea ecx,[ecx+ecx*2]
2901
		add ecx,buf2d_data
2902
		sub ebx,eax
2903
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2904
 
2927 IgorA 2905
	mov dword[lost_bytes],0
1535 IgorA 2906
	mov ecx,[coord_x]
2927 IgorA 2907
	cmp ecx,0
2908
	jge @f
2909
		neg ecx
2910
		;inc ecx
2911
		cmp eax,ecx ;eax - ширина копируемой картинки
2912
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2913
		shl ecx,2
2914
		mov [lost_bytes],ecx
2915
		add esi,ecx
2916
		shr ecx,2
2917
		sub eax,ecx ;укорачиваем копируемую строку
2918
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2919
		lea ecx,[ecx+ecx*2]
2920
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2921
		xor ecx,ecx
2922
	@@:
1535 IgorA 2923
	cmp ecx,ebx
2927 IgorA 2924
	jle @f
1535 IgorA 2925
		sub ecx,ebx
2926
		sub eax,ecx ;укорачиваем копируемую строку
2927
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2927 IgorA 2928
		shl ecx,2 ;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2929
		add [lost_bytes],ecx
1535 IgorA 2930
	@@:
2931
 
2927 IgorA 2932
;	mov [right_bytes],0
2933
;	mov ecx,[coord_x]
2934
;	cmp ecx,ebx
2935
;	jl @f
2936
;		sub ecx,ebx
2937
;		sub eax,ecx ;укорачиваем копируемую строку
2938
;		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2939
;		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2940
;		mov [right_bytes],ecx
2941
;	@@:
2942
 
1535 IgorA 2943
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2658 IgorA 2944
 
1535 IgorA 2945
	cld
2927 IgorA 2946
	cmp [lost_bytes],0
1535 IgorA 2947
	jg .copy_1
2948
	.copy_0: ;простое копирование
2949
		mov ecx,eax
2950
		@@:
2920 IgorA 2951
			call combine_colors_0
1535 IgorA 2952
			add edi,3
2953
			add esi,4
2954
			loop @b
2955
		add edi,ebx
2956
		dec edx
2957
		cmp edx,0
2958
		jg .copy_0
2959
	jmp .copy_end
2960
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2961
		mov ecx,eax
2962
		@@:
2920 IgorA 2963
			call combine_colors_0
1535 IgorA 2964
			add edi,3
2965
			add esi,4
2966
			loop @b
2967
		add edi,ebx
2927 IgorA 2968
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 2969
		dec edx
2970
		cmp edx,0
2971
		jg .copy_1
2972
 
2973
	.copy_end:
2974
	popad
2975
	ret
2976
endp
2977
 
2978
;input:
2979
; ebx - color1
2980
; esi = pointer to transparent
2981
; edi = pointer to background color2
2982
;output:
2983
; [edi] = combine color
2984
align 4
2985
combine_colors_2:
2986
	push ax ebx cx dx si
2987
	mov cl,byte[esi] ;pro
2988
	xor ch,ch
2989
	mov si,0x00ff ;---get transparent---
2990
	sub si,cx ;256-pro
2991
 
1653 IgorA 2992
		;---blye---
2748 IgorA 2993
		movzx ax,bl
1535 IgorA 2994
		shr ebx,8
2995
		imul ax,si
2748 IgorA 2996
		movzx dx,byte[edi]
1535 IgorA 2997
		imul dx,cx
2998
		add ax,dx
1653 IgorA 2999
		mov byte[edi],ah
1535 IgorA 3000
		;---green---
2748 IgorA 3001
		movzx ax,bl
1535 IgorA 3002
		shr ebx,8
3003
		imul ax,si
2748 IgorA 3004
		movzx dx,byte[edi+1]
1535 IgorA 3005
		imul dx,cx
3006
		add ax,dx
3007
		mov byte[edi+1],ah
3008
		;---red---
2748 IgorA 3009
		movzx ax,bl
1535 IgorA 3010
		imul ax,si
2748 IgorA 3011
		movzx dx,byte[edi+2]
1535 IgorA 3012
		imul dx,cx
3013
		add ax,dx
1653 IgorA 3014
		mov byte[edi+2],ah
1535 IgorA 3015
 
3016
	pop si dx cx ebx ax
3017
	ret
3018
 
3019
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
3020
; указываются координаты вставки буфера buf_source относительно buf_destination
3021
align 4
3022
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
3023
	locals
2383 IgorA 3024
		lost_bytes dd ? ;число потерянных байтов в строке копируемого изображеня (тех что не влазят в буфер)
1535 IgorA 3025
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
3026
	endl
3027
	pushad
3028
 
3029
	mov edi,[buf_source]
3030
	cmp buf2d_bits,8
3031
	jne .error1 ;формат буфера не поодерживается
2383 IgorA 3032
	mov eax,buf2d_w ;ширина копируемой картинки
1535 IgorA 3033
	mov edx,buf2d_h ;высота копируемой картинки
3034
	mov esi,buf2d_data ;данные копируемой картинки
3035
 
3036
	mov edi,[buf_destination]
3037
	cmp buf2d_bits,24
3038
	jne .error2 ;формат буфера не поодерживается
1642 IgorA 3039
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
3040
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 3041
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 3042
		mov ebx,buf2d_h ;ebx - высота основного буфера
3043
		mov ecx,[coord_y]
2367 IgorA 3044
		cmp ecx,0
3045
		jge @f
3046
			;если координата coord_y<0 (1-я настройка)
3047
			add edx,ecx ;уменьшаем высоту копируемой картинки
2383 IgorA 3048
			cmp edx,0
3049
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2367 IgorA 3050
			neg ecx
3051
			;inc ecx
3052
			imul ecx,eax
3053
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
3054
			xor ecx,ecx ;обнуляем координату coord_y
3055
		@@:
1535 IgorA 3056
		cmp ecx,ebx
3057
		jge .copy_end ;если координата 'y' больше высоты буфера
3058
		add ecx,edx ;ecx - нижняя координата копируемой картинки
3059
		cmp ecx,ebx
3060
		jle @f
3061
			sub ecx,ebx
3062
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
3063
		@@:
3064
		mov ebx,buf2d_w
2367 IgorA 3065
		mov ecx,[coord_y] ;ecx используем для временных целей
3066
		cmp ecx,0
2383 IgorA 3067
		jg .end_otr_c_y
3068
			;если координата coord_y<=0 (2-я настройка)
2367 IgorA 3069
			mov ecx,[coord_x]
3070
			jmp @f
3071
		.end_otr_c_y:
3072
		imul ecx,ebx
1535 IgorA 3073
		add ecx,[coord_x]
2367 IgorA 3074
		@@:
1535 IgorA 3075
		lea ecx,[ecx+ecx*2]
2383 IgorA 3076
		add ecx,buf2d_data ;buf2d_data данные основного буфера
3077
		sub ebx,eax ;ebx - ширина основного буфера минус ширина рисуемого буфера
1535 IgorA 3078
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3079
 
2383 IgorA 3080
	mov dword[lost_bytes],0
1535 IgorA 3081
	mov ecx,[coord_x]
2383 IgorA 3082
	cmp ecx,0
3083
	jge @f
3084
		neg ecx
3085
		;inc ecx
3086
		cmp eax,ecx ;eax - ширина копируемой картинки
3087
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2927 IgorA 3088
		mov [lost_bytes],ecx
2383 IgorA 3089
		sub eax,ecx ;укорачиваем копируемую строку
3090
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3091
		add esi,ecx
3092
		lea ecx,[ecx+ecx*2]
3093
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3094
		xor ecx,ecx
3095
	@@:
1535 IgorA 3096
	cmp ecx,ebx
2383 IgorA 3097
	jle @f
1535 IgorA 3098
		sub ecx,ebx
3099
		sub eax,ecx ;укорачиваем копируемую строку
3100
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3101
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2383 IgorA 3102
		add [lost_bytes],ecx
1535 IgorA 3103
	@@:
3104
 
3105
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
3106
	mov [dest_w_bytes],ebx
3107
	mov ebx,[color]
3108
 
3109
	cld
2383 IgorA 3110
	cmp dword[lost_bytes],0
1535 IgorA 3111
	jg .copy_1
3112
	.copy_0: ;простое копирование
3113
		mov ecx,eax
3114
		@@:
3115
			call combine_colors_2
3116
			add edi,3
3117
			inc esi
3118
			loop @b
3119
		add edi,[dest_w_bytes]
3120
		dec edx
3121
		cmp edx,0
3122
		jg .copy_0
3123
	jmp .copy_end
2383 IgorA 3124
	.copy_1: ;не простое копирование (картинка вылазит за левую и/или правую сторону)
1535 IgorA 3125
		mov ecx,eax
3126
		@@:
3127
			call combine_colors_2
3128
			add edi,3
3129
			inc esi
3130
			loop @b
3131
		add edi,[dest_w_bytes]
2383 IgorA 3132
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 3133
		dec edx
3134
		cmp edx,0
3135
		jg .copy_1
3136
 
3137
	jmp .copy_end
3138
	.error1:
3139
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
3140
		jmp .copy_end
3141
	.error2:
3142
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
3143
	.copy_end:
3144
	popad
3145
	ret
3146
endp
3147
 
3148
;преобразование 8-битного буфера размером 16*16 в размер 1*256 символов
3149
align 4
3150
proc buf_convert_text_matrix, buf_struc:dword
3151
	locals
3152
		tmp_mem dd ?
3153
		c1 dw ?
3154
		c2 dd ?
3155
		c3 dw ?
3156
	endl
3157
	pushad
3158
	mov edi,dword[buf_struc]
3159
	cmp buf2d_bits,8
3160
	jne .error
3161
		mov ecx,buf2d_h
3162
		mov ebx,ecx
3163
		shr ebx,4 ;предполагаем что в буфере 16 строк с символами, потому делим на 2^4
3164
		mov edx,buf2d_w
3165
		imul ecx,edx ;ecx = size  8 b
3166
		invoke mem.alloc,ecx ;выделяем временную память
3167
		mov [tmp_mem],eax ;eax - new memory
3168
 
3169
		shr edx,4 ;предполагаем что в буфере 16 колонок с символами, потому делим на 2^4
3170
		mov eax,ebx
3171
		imul ebx,edx ;вычисляем кооличество пикселей на 1 символ
3172
		;eax = bhe - высота буквы
3173
		;ebx = bwi*bhe - колличество пикселей в 1-й букве
3174
		;edx = bwi - ширина буквы
3175
		;ecx,esi,edi - используются в цикле .c_0
3176
		shr buf2d_w,4
3177
		shl buf2d_h,4 ;преобразовываем размеры буфера
3178
 
3179
		cld
3180
		mov esi,buf2d_data
3181
		mov edi,[tmp_mem]
3182
		mov word[c3],16
3183
		.c_3:
3184
			mov dword[c2],eax
3185
			.c_2:
3186
				mov word[c1],16
3187
				.c_1:
3188
					mov ecx,edx ;.c_0:
3189
					rep movsb
3190
					add edi,ebx
3191
					sub edi,edx ;edi+=(bwi*bhe-bwi)
3192
					dec word[c1]
3193
					cmp word[c1],0
3194
					jg .c_1
3195
				add edi,edx
3196
				shl ebx,4
3197
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
3198
				shr ebx,4
3199
				dec dword[c2]
3200
				cmp dword[c2],0
3201
				jg .c_2
3202
			sub edi,ebx
3203
			shl ebx,4
3204
			add edi,ebx ;edi+=(15*bwi*bhe)
3205
			shr ebx,4
3206
			dec word[c3]
3207
			cmp word[c3],0
3208
			jg .c_3
3209
 
3210
		mov edi,dword[buf_struc] ;копирование новой матрицы в основной буфер
3211
		mov edi,buf2d_data
3212
		mov esi,[tmp_mem]
3213
		mov ecx,ebx
3214
		shl ecx,8
3215
		rep movsb
3216
		invoke mem.free,[tmp_mem] ;чистим временную память
3217
		jmp .end_conv
3218
	.error:
3219
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
3220
	.end_conv:
3221
	popad
3222
	ret
3223
endp
3224
 
3225
align 4
3226
buf_s_matr buf_2d_header ? ;локальная матрица символа
3227
 
3228
align 4
3229
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
3230
	locals
3231
		buf_t_matr_offs dd ?
3232
	endl
3233
	pushad
3234
	mov edi,dword[buf_struc]
3235
	cmp buf2d_bits,24
3236
	jne .error2
3237
	mov edi,dword[buf_t_matr]
3238
	cmp buf2d_bits,8
3239
	jne .error1
3240
		mov edx,buf2d_data
3241
		mov [buf_t_matr_offs],edx
3242
		mov ecx,BUF_STRUCT_SIZE ;копируем структуру текстовой матрицы
3243
		mov esi,edi
3244
		lea edi,[buf_s_matr]
3245
		cld
3246
		rep movsb
3247
		lea edi,[buf_s_matr]
3248
		shr buf2d_h,8 ;делим высоту символьного буфера на 256, для нахождения высоты 1-го символа
3249
		mov ebx,buf2d_h ;берем высоту символа
3250
		mov ecx,buf2d_w ;берем ширину символа
3251
 
3252
		mov eax,[coord_x]
3253
		mov esi,[text]
3254
		cmp byte[esi],0
3255
		je .end_draw ;если пустая строка
3256
		@@:
3257
			xor edx,edx
3258
			mov dl,byte[esi] ;берем код символа
3259
			imul edx,ebx ;умножаем его на высоту символа
3260
			imul edx,ecx ;умножаем на ширину символа
3261
			add edx,[buf_t_matr_offs] ;прибавляем смещение 0-го символа, т. е. получается смещение выводимого символа
3262
			mov buf2d_data,edx ;в локальный буфер символа, ставим указатель на нужный символ из буфера buf_t_matr
3263
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
3264
			add eax,ecx
3265
			.new_s:
3266
				inc esi
3267
				cmp byte[esi],13
3268
				jne .no_13
3269
					mov eax,[coord_x]
3270
					add [coord_y],ebx
3271
					jmp .new_s
3272
				.no_13:
3273
			cmp byte[esi],0
3274
			jne @b
3275
		jmp .end_draw
3276
	.error1:
3277
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
3278
		jmp .end_draw
3279
	.error2:
3280
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
3281
	.end_draw:
3282
	popad
3283
	ret
3284
endp
3285
 
3286
align 4
3287
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
3288
	pushad
3289
	mov eax,63
3290
	mov ebx,1
3291
 
3292
	mov esi,[fun]
3293
	@@:
3294
		mov cl,byte[esi]
3295
		int 0x40
3296
		inc esi
3297
		cmp byte[esi],0
3298
		jne @b
3299
	mov cl,':'
3300
	int 0x40
3301
	mov cl,' '
3302
	int 0x40
3303
	mov esi,[mes]
3304
	@@:
3305
		mov cl,byte[esi]
3306
		int 0x40
3307
		inc esi
3308
		cmp byte[esi],0
3309
		jne @b
3310
	popad
3311
	ret
3312
endp
3313
 
3314
;input:
3315
; ebp+8  = p0
3316
; ebp+12 = p1
3317
align 4
3318
line_len4i:
3319
	push ebp
3320
	mov ebp,esp
3321
		finit
3322
		fild word [ebp+8]
3323
		fisub word [ebp+12]
3324
		fmul st0,st0 ;st0=x^2
3325
		fild word [ebp+10]
3326
		fisub word [ebp+14]
3327
		fmul st0,st0 ;st0=y^2
3328
		fadd st0,st1
3329
		fsqrt
3330
		fstp dword [ebp+12]
3331
	pop ebp
3332
	ret 4 ;8
3333
 
3334
align 4
1727 IgorA 3335
proc buf_curve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
1535 IgorA 3336
	locals
3337
		delt_t dd ?
3338
		opr_param dd ?
3339
		v_poi_0 dd ?
3340
	endl
3341
	pushad
3342
 
3343
;float t, xt,yt;
3344
;for(t=.0;t<1.;t+=.005){
3345
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
3346
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
3347
;  dc.SetPixel(xt,yt,255L);
3348
;}
3349
 
1727 IgorA 3350
	mov edx,[color] ;set curve color
1535 IgorA 3351
	mov edi,[buffer]
3352
	xor ebx,ebx
3353
	xor ecx,ecx
3354
 
3355
	finit
3356
 
3357
	; calculate delta t
3358
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
3359
	fadd dword[esp]
3360
	add esp,4 ;pop ...
3361
 
3362
	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
3363
	fadd dword[esp]
3364
	add esp,4 ;pop ...
3365
 
3366
	fadd st0,st0 ; len*=2
3367
	ftst
3368
	fstsw ax
3369
 
3370
	fld1
3371
	sahf
3372
	jle @f ;избегаем деления на 0
3373
		fdiv st0,st1
3374
	@@:
3375
	fstp dword[delt_t]
3376
 
3377
	finit
3378
 
3379
	;fild word[coord_p2+2] ;y2
3380
	fild word[coord_p1+2] ;y1
3381
	fild word[coord_p0+2] ;y0
3382
	fild word[coord_p2] ;x2
3383
	fild word[coord_p1] ;x1
3384
	fild word[coord_p0] ;x0
3385
	fld dword[delt_t]
3386
	fldz ;t=.0
3387
 
3388
	@@:
3389
		fld1
3390
		fsub st0,st1 ;1.-t
3391
		fmul st0,st0 ;pow(1.-t,2)
3392
		fmul st0,st3 ;...*x0
3393
		fstp dword[opr_param]
3394
 
3395
		fld1
3396
		fsub st0,st1 ;1.-t
3397
		fmul st0,st1 ;(1.-t)*t
3398
		fadd st0,st0
3399
		fmul st0,st4 ;...*x1
3400
		mov esi,dword[opr_param]
3401
		fstp dword[opr_param]
3402
 
3403
		fldz
3404
		fadd st0,st1 ;0+t
3405
		fmul st0,st0 ;t*t
3406
		fmul st0,st5 ;...*x2
3407
 
3408
		fadd dword[opr_param]
3409
		mov dword[opr_param],esi
3410
		fadd dword[opr_param]
3411
		fistp word[v_poi_0] ;x
3412
 
3413
		fld1
3414
		fsub st0,st1 ;1.-t
3415
		fmul st0,st0 ;pow(1.-t,2)
3416
		fmul st0,st6 ;...*y0
3417
		fstp dword[opr_param]
3418
 
3419
		fld1
3420
		fsub st0,st1 ;1.-t
3421
		fmul st0,st1 ;(1.-t)*t
3422
		fadd st0,st0
3423
		fmul st0,st7 ;...*y1
3424
		mov esi,dword[opr_param]
3425
		fstp dword[opr_param]
3426
 
3427
		fldz
3428
		fadd st0,st1 ;0+t
3429
		fmul st0,st0 ;t*t
3430
		fimul word[coord_p2+2] ;...*y2
3431
 
3432
		fadd dword[opr_param]
3433
		mov dword[opr_param],esi
3434
		fadd dword[opr_param]
3435
		fistp word[v_poi_0+2] ;y
3436
 
3437
		mov eax,1
3438
		mov bx,word[v_poi_0+2]
3439
		mov cx,word[v_poi_0]
3440
		call draw_pixel
3441
 
3442
		fadd st0,st1 ;t+dt
3443
 
3444
		fld1
3445
		fcomp
3446
		fstsw ax
3447
		sahf
3448
	jae @b
3449
 
3450
	popad
3451
	ret
3452
endp
3453
 
3105 IgorA 3454
;фильтер
3455
align 4
3456
proc buf_filter_dither, buffer:dword, algor:dword
3457
	pushad
3458
	mov edi,[buffer]
3459
	cmp buf2d_bits,24
3460
	jne .error
3461
		mov edx,buf2d_w
3462
		mov esi,buf2d_h
3463
		mov edi,buf2d_data
3464
;edi - pointer to 24bit bitmap
3465
;edx - x size
3466
;esi - y size
3467
		lea   edx,[edx*3]
3468
		imul  esi,edx
2748 IgorA 3469
 
3105 IgorA 3470
		;определяем какой алгоритм использовать
3471
		cmp dword[algor],0
3472
		jne @f
3473
			call dither_0
3474
			jmp .dither_end
3475
		@@:
3476
		cmp dword[algor],1
3477
		jne @f
3478
			call dither_1
3479
			jmp .dither_end
3480
		@@:
3481
		call dither_2
3482
		jmp .dither_end
3483
	.error:
3484
		stdcall print_err,sz_buf2d_filter_dither,txt_err_n24b
3485
	.dither_end:
3486
	popad
3487
	ret
3488
endp
2748 IgorA 3489
 
3105 IgorA 3490
align 16
3491
dither_0: ; Sierra Filter Lite algoritm
3492
newp_0:   ; Dithering cycle
3493
	xor   ebx,ebx ; At first threshold
3494
	movzx ecx,byte[edi]
3495
	cmp   cl,255
3496
	je    newp_0.next
3497
	test  cl,cl
3498
	jz    newp_0.next
3499
	jns   @f
3500
	dec   ebx
3501
	sub   ecx,255
3502
@@:
3503
	mov   [edi],bl               ; putpixel
3504
 
3505
	sar   ecx,1                  ; error/2
3506
	;adc   ecx,0                  ; round to integer
3507
 
3508
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3509
	add   eax,ecx                ; add error/2 to (x+1;y)
3510
	jge   @f                     ; check_overflow
3511
	xor   eax,eax
3512
	jmp   .ok
3513
@@:
3514
	cmp   eax,255
3515
	jle   .ok
3516
	or    al,255
3517
.ok:
3518
	mov   [edi+3],al             ; putpixel
3519
 
3520
	sar   ecx,1                  ; error/4
3521
	adc   ecx,0                  ; round to integer
3522
 
3523
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3524
	add   eax,ecx                ; add error/4 to (x-1;y+1)
3525
	jge   @f                     ; check_overflow
3526
	xor   eax,eax
3527
	jmp   .ok1
3528
@@:
3529
	cmp   eax,255
3530
	jle   .ok1
3531
	or    al,255
3532
.ok1:
3533
	mov   [edi+edx-3],al         ; putpixel
3534
 
3535
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3536
	add   eax,ecx                ; add error/4 to (x;y+1)
3537
	jge   @f                     ; check_overflow
3538
	xor   eax,eax
3539
	jmp   .ok2
3540
@@:
3541
	cmp   eax,255
3542
	jle   .ok2
3543
	or    al,255
3544
.ok2:
3545
	mov   [edi+edx],al           ; putpixel
3546
 
3547
.next:
3548
	inc   edi
3549
	dec   esi
3550
	jnz   newp_0
3551
	ret
3552
 
3553
align 16
3554
dither_1: ; Floyd-Steinberg algoritm
3555
newp_1:   ; Dithering cycle
3556
	xor   ebx,ebx ; At first threshold
3557
	movzx ecx,byte[edi]
3558
	cmp   cl,255
3559
	je    newp_1.next
3560
	test  cl,cl
3561
	jz    newp_1.next
3562
	jns   @f
3563
	dec   ebx
3564
	sub   ecx,255
3565
@@:
3566
	mov   [edi],bl               ; putpixel
3567
 
3568
	sar   ecx,4                  ; error/16
3569
	adc   ecx,0                  ; round to integer
3570
	mov   ebx,ecx
3571
 
3572
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3573
	add   eax,ecx                ; add error/16 to (x+1;y+1)
3574
	jge   @f                     ; check_overflow
3575
	xor   eax,eax
3576
	jmp   .ok
3577
@@:
3578
	cmp   eax,255
3579
	jle   .ok
3580
	or    al,255
3581
.ok:
3582
	mov   [edi+edx+3],al         ;putpixel
3583
 
3584
	imul  ecx,3
3585
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3586
	add   eax,ecx                ; add 3*error/16 to (x-1;y+1)
3587
	jge   @f                     ; check_overflow
3588
	xor   eax,eax
3589
	jmp   .ok1
3590
@@:
3591
	cmp   eax,255
3592
	jle   .ok1
3593
	or    al,255
3594
.ok1:
3595
	mov   [edi+edx-3],al         ;putpixel
3596
 
3597
	mov   ecx,ebx
3598
	imul  ecx,5
3599
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3600
	add   eax,ecx                ; add 5*error/16 to (x;y+1)
3601
	jge   @f                     ; check_overflow
3602
	xor   eax,eax
3603
	jmp   .ok2
3604
@@:
3605
	cmp   eax,255
3606
	jle   .ok2
3607
	or    al,255
3608
.ok2:
3609
	mov   [edi+edx],al           ;putpixel
3610
 
3611
	mov   ecx,ebx
3612
	imul  ecx,7
3613
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3614
	add   eax,ecx                ; add 7*error/16 to (x+1;y)
3615
	jge   @f                     ; check_overflow
3616
	xor   eax,eax
3617
	jmp   .ok3
3618
@@:
3619
	cmp   eax,255
3620
	jle   .ok3
3621
	or    al,255
3622
.ok3:
3623
	mov   [edi+3],al             ;putpixel
3624
 
3625
.next:
3626
	inc  edi
3627
	dec  esi
3628
	jnz  newp_1
3629
	ret
3630
 
3631
align 16
3632
dither_2: ; Burkers algoritm
3633
newp_2:   ; Dithering cycle
3634
	xor   ebx,ebx ; At first threshold
3635
	movsx ecx,byte[edi]
3636
	cmp   cl,255
3637
	je    newp_2.next
3638
	test  cl,cl
3639
	jz    newp_2.next
3640
	jns   @f
3641
	dec   ebx
3642
@@:
3643
	mov   [edi],bl               ; putpixel
3644
 
3645
	sar   ecx,2                  ; error/4
3646
	adc   ecx,0                  ; round to integer
3647
 
3648
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3649
	add   eax,ecx                ; add error/4 to (x+1;y)
3650
	jge   @f                     ; check_overflow
3651
	xor   eax,eax
3652
	jmp   .ok
3653
@@:
3654
	cmp   eax,255
3655
	jle   .ok
3656
	or    al,255
3657
.ok:
3658
	mov   [edi+3],al             ; putpixel
3659
 
3660
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3661
	add   eax,ecx                ; add error/4 to (x;y+1)
3662
	jge   @f                     ; check_overflow
3663
	xor   eax,eax
3664
	jmp   .ok1
3665
@@:
3666
	cmp   eax,255
3667
	jle   .ok1
3668
	or    al,255
3669
.ok1:
3670
	mov   [edi+edx],al           ; putpixel
3671
 
3672
	sar   ecx,1                  ; error/8
3673
	adc   ecx,0                  ; round to integer
3674
 
3675
	movzx eax,byte[edi+6]        ; pixel (x+2;y)
3676
	add   eax,ecx                ; add error/8 to (x+2;y)
3677
	jge   @f                     ; check_overflow
3678
	xor   eax,eax
3679
	jmp   .ok2
3680
@@:
3681
	cmp   eax,255
3682
	jle   .ok2
3683
	or    al,255
3684
.ok2:
3685
	mov   [edi+6],al             ; putpixel
3686
 
3687
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3688
	add   eax,ecx                ; add error/8 to (x-1;y+1)
3689
	jge   @f                     ; check_overflow
3690
	xor   eax,eax
3691
	jmp   .ok3
3692
@@:
3693
	cmp   eax,255
3694
	jle   .ok3
3695
	or    al,255
3696
.ok3:
3697
	mov   [edi+edx-3],al         ; putpixel
3698
 
3699
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3700
	add   eax,ecx                ; add error/8 to (x+1;y+1)
3701
	jge   @f                     ; check_overflow
3702
	xor   eax,eax
3703
	jmp   .ok4
3704
@@:
3705
	cmp   eax,255
3706
	jle   .ok4
3707
	or    al,255
3708
.ok4:
3709
	mov   [edi+edx+3],al         ; putpixel
3710
 
3711
	sar   ecx,1                  ; error/16
3712
	;adc   ecx,0                  ; round to integer
3713
 
3714
	movzx eax,byte[edi+edx-6]    ; pixel (x-2;y+1)
3715
	add   eax,ecx                ; add error/16 to (x-2;y+1)
3716
	jge   @f                     ; check_overflow
3717
	xor   eax,eax
3718
	jmp   .ok5
3719
@@:
3720
	cmp   eax,255
3721
	jle   .ok5
3722
	or    al,255
3723
.ok5:
3724
	mov   [edi+edx-6],al         ; putpixel
3725
 
3726
	movzx eax,byte[edi+edx+6]    ; pixel (x+2;y+1)
3727
	add   eax,ecx                ; add error/16 to (x+2;y+1)
3728
	jge   @f                     ; check_overflow
3729
	xor   eax,eax
3730
	jmp   .ok6
3731
@@:
3732
	cmp   eax,255
3733
	jle   .ok6
3734
	or    al,255
3735
.ok6:
3736
	mov   [edi+edx+6],al         ; putpixel
3737
 
3738
.next:
3739
	inc   edi
3740
	dec   esi
3741
	jnz   newp_2
3742
	ret
3743
 
3744
 
3745
 
2748 IgorA 3746
;*** функции для работы с воксельной графикой ***
3747
 
3748
 
3749
 
3750
;создание воксельных кистей
3751
align 4
3752
proc vox_brush_create uses eax ebx ecx edi, h_br:dword, buf_z:dword
3753
	mov edi,[h_br]
3754
	movzx ecx,byte[edi+3]
3755
	add edi,4
3756
 
3757
	; *** создание единичной кисти ***
3758
	mov eax,[buf_z]
3759
	mov buf2d_data,eax
3760
	movzx eax,byte[edi-4] ;ширина единичной кисти
3761
	mov buf2d_w,eax ;ширина буфера
3762
	movzx eax,byte[edi-4+1] ;высота единичной кисти
3763
	mov buf2d_h,eax ;высота буфера
3764
	mov buf2d_size_lt,0 ;отступ слева и справа для буфера
3765
	mov buf2d_color,0 ;цвет фона буфера
3766
	mov buf2d_bits,32 ;количество бит в 1-й точке изображения
3767
 
3768
	; *** создание следующих кистей ***
3769
	cmp ecx,1
3770
	jl .end_creat
3771
	movzx ebx,byte[edi-4+2] ;высота основания единичной кисти
3772
	shr ebx,1
3773
	cld
3774
	@@:
3775
		mov eax,edi
3776
		add edi,BUF_STRUCT_SIZE
3777
		stdcall vox_create_next_brush, eax, edi, ebx
3778
		shl ebx,1
3779
		loop @b
3780
	.end_creat:
3781
	ret
3782
endp
3783
 
3784
;удаление воксельных кистей
3785
align 4
3786
proc vox_brush_delete uses ecx edi, h_br:dword
3787
	mov edi,[h_br]
3788
	movzx ecx,byte[edi+3]
3789
	add edi,4
3790
 
3791
	; *** удаление кистей ***
3792
	cmp ecx,1
3793
	jl .end_delete
3794
	cld
3795
	@@:
3796
		add edi,BUF_STRUCT_SIZE
3797
		stdcall buf_delete, edi
3798
		loop @b
3799
	.end_delete:
3800
	ret
3801
endp
3802
 
3803
;функция для создания вокселя следующего порядка
3804
; buf_v1 - буфер с исходным вокселем
3805
; buf_v2 - буфер с увеличеным вокселем
3806
; h - высота основания исходного вокселя : 2
3807
align 4
3808
proc vox_create_next_brush uses eax ebx ecx edx edi, buf_v1:dword, buf_v2:dword, h:dword
3809
	mov edi,[buf_v1]
3810
	mov ebx,buf2d_h
3811
	mov ecx,buf2d_w
3812
	mov edi,[buf_v2]
3813
	mov buf2d_h,ebx
3814
	shl buf2d_h,1
3815
	mov buf2d_w,ecx
3816
	shl buf2d_w,1
3817
	mov buf2d_color,0
3818
	mov buf2d_bits,32
3819
 
3820
	stdcall buf_create, [buf_v2] ;создание буфера глубины
3821
	shr ecx,1
3822
	mov edx,[h]
3823
	shl edx,1
3824
	sub ebx,edx
3825
	;ecx - ширина исходного вокселя : 2
3826
	;ebx - высота исходного вокселя (без основания)
3827
	;edx - высота основания исходного вокселя
3828
	mov eax,[h]
2975 IgorA 3829
	cmp eax,0
3830
	je @f
3831
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,0
3832
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,0
2748 IgorA 3833
 
2975 IgorA 3834
		stdcall vox_add, [buf_v2], [buf_v1], 0,eax,eax
3835
		push eax ;stdcall ...
3836
		add eax,ebx
3837
		stdcall vox_add, [buf_v2], [buf_v1], 0,eax ;,...
3838
		sub eax,ebx
3839
		shl ecx,1
2748 IgorA 3840
 
2975 IgorA 3841
		;ecx - ширина исходного вокселя
3842
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax,eax
3843
		push eax ;stdcall ...,[h]
3844
		add eax,ebx
3845
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax;,[h]
3846
		;sub eax,ebx
3847
		shr ecx,1
2748 IgorA 3848
 
2975 IgorA 3849
		;ecx - ширина исходного вокселя : 2
3850
		stdcall vox_add, [buf_v2], [buf_v1], ecx,edx,edx
3851
		add ebx,edx
3852
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,edx
3853
 
3854
		jmp .end_0
3855
	@@:
3856
		;если h = 0, тогда получаем кисть на 2 грани
3857
		;в таком случае для получения глубины берем ширину / 2
3858
		mov eax,ecx
3859
		;2 левых вокселя
3860
		stdcall vox_add, [buf_v2], [buf_v1], 0,0,eax
3861
		stdcall vox_add, [buf_v2], [buf_v1], 0,ebx,eax
3862
		shl eax,1
3863
		;2 центральных передних вокселя (задние центральные не выводим)
3864
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
3865
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax
3866
		shr eax,1
3867
		shl ecx,1
3868
		;2 правых вокселя
3869
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
3870
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax
3871
 
3872
	.end_0:
3873
 
3874
 
2748 IgorA 3875
	ret
3876
endp
3877
 
3878
;
3879
align 4
2758 IgorA 3880
proc vox_add, buf_v1:dword, buf_v2:dword, coord_x:dword, coord_y:dword, coord_z:dword
2748 IgorA 3881
pushad
2759 IgorA 3882
	mov ebx,[coord_x]
3883
	mov eax,[coord_y]
2748 IgorA 3884
	mov edi,[buf_v2]
3885
	mov ecx,buf2d_h
3886
	mov esi,buf2d_w
3887
	imul ecx,esi
2759 IgorA 3888
	add esi,ebx
2748 IgorA 3889
	mov edx,buf2d_data
3890
	cld
3891
	;ecx - count pixels in voxel
3892
	;edx - указатель на данные в воксельном буфере
3893
	;edi - указатель на воксельный буфер
3894
	;esi - width voxel buffer add coord x
3895
	.cycle:
3896
		cmp dword[edx],0
3897
		je @f
3898
			;проверяем буфер глубины
2759 IgorA 3899
			push eax ecx edi esi
2748 IgorA 3900
			mov ecx,eax
2759 IgorA 3901
			mov edi,[buf_v1]
3902
			call get_pixel_32 ;stdcall buf_get_pixel, [buf_v1],ebx,ecx
2748 IgorA 3903
			mov esi,[edx]
3904
			add esi,[coord_z]
3905
			cmp eax,esi
3906
			jge .end_draw
2759 IgorA 3907
			stdcall buf_set_pixel, [buf_v1],ebx,ecx,esi ;esi = new coord z
2748 IgorA 3908
			.end_draw:
2759 IgorA 3909
			pop esi edi ecx eax
2748 IgorA 3910
		@@:
3911
		add edx,4
2759 IgorA 3912
		inc ebx
3913
		cmp ebx,esi
2748 IgorA 3914
		jl @f
2759 IgorA 3915
			inc eax
3916
			sub ebx,buf2d_w
2748 IgorA 3917
		@@:
3918
		loop .cycle
3919
popad
3920
	ret
3921
endp
3922
 
2758 IgorA 3923
;description:
3924
; возврашает ширину воксельного изображения с 3-мя гранями
3925
; принимает указатель на кисть и масштаб
3926
align 4
3927
proc buf_vox_obj_get_img_w_3g uses ecx, h_br:dword,k_scale:dword
3928
	mov ecx,[h_br]
3929
 
3930
	movzx eax,byte[ecx]
3931
	cmp dword[k_scale],1
3932
	jl .end_c0
3933
		mov ecx,[k_scale]
3934
		shl eax,cl
3935
	.end_c0:
3936
	ret
3937
endp
3938
 
3939
;description:
3940
; возврашает высоту воксельного изображения с 3-мя гранями
3941
; принимает указатель на кисть и масштаб
3942
align 4
3943
proc buf_vox_obj_get_img_h_3g uses ecx, h_br:dword,k_scale:dword
3944
	mov ecx,[h_br]
3945
 
3946
	movzx eax,byte[ecx+1]
3947
	cmp dword[k_scale],1
3948
	jl .end_c0
3949
		mov ecx,[k_scale]
3950
		shl eax,cl
3951
	.end_c0:
3952
	ret
3953
endp
3954
 
3955
;description:
2815 IgorA 3956
; функция рисующая воксельный объект (видна 1 грань)
2758 IgorA 3957
;input:
3958
; buf_i - буфер в котором рисуется (24 бита)
3959
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2815 IgorA 3960
align 4
3961
proc buf_vox_obj_draw_1g, buf_i:dword, buf_z:dword, v_obj:dword, coord_x:dword,\
3962
coord_y:dword, k_scale:dword
3963
	cmp [k_scale],0
3964
	jl .end_f
3965
pushad
3966
	mov edi,[buf_i]
3967
	cmp buf2d_bits,24
3968
	jne .error1
3969
	mov edi,[buf_z]
3970
	cmp buf2d_bits,32
3971
	jne .error2
3972
 
3973
	mov ecx,[k_scale]
3974
	mov ebx,[coord_x]
3975
	mov edx,[coord_y]
3976
	mov edi,[v_obj]
3977
	add edi,vox_offs_data
3978
	xor esi,esi
3979
	stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
3980
 
3981
	jmp .end_0
3982
	.error1:
3983
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n24b
3984
		jmp .end_0
3985
	.error2:
3986
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n32b
3987
	.end_0:
3988
popad
3989
	.end_f:
3990
	ret
3991
endp
3992
 
3993
;input:
3994
; ebx - coord_x
3995
; edx - coord_y
3996
; esi - coord_z
3997
; ecx - уровень текушего узла
3998
; edi - указатель на данные воксельного объекта
3999
align 4
4000
proc draw_sub_vox_obj_1g, buf_i:dword, buf_z:dword, v_obj:dword
4001
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4002
	je .sub_trees
4003
 
4004
		;прорисовка рамки если размер узла = 1
4005
		cmp ecx,0
4006
		jne @f
4007
			;проверка глубины esi
4008
			stdcall buf_get_pixel, [buf_z], ebx,edx, esi
4009
			cmp eax,esi
4010
			jge @f
4011
				push ecx
4012
				mov ecx,dword[edi]
4013
				and ecx,0xffffff
4014
				stdcall buf_set_pixel, [buf_i], ebx,edx, ecx
4015
				stdcall buf_set_pixel, [buf_z], ebx,edx, esi
4016
				pop ecx
4017
		@@:
4018
 
4019
		;рекурсивный перебор поддеревьев
4020
		push edx
4021
		;вход внутрь узла
4022
		dec ecx
4023
 
4024
		mov eax,1
4025
		cmp ecx,1
4026
		jl @f
4027
			shl eax,cl
4028
		@@:
4029
 
4030
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4031
 
4032
		mov ah,byte[edi+3]
4033
		add edi,4
4034
		mov al,8
4035
		.cycle:
4036
			bt ax,8 ;тестируем только ah
4037
			jnc .c_next
4038
				push eax ebx edx esi
4039
				stdcall vox_corect_coords_pl, [v_obj],1
4040
				stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
4041
				pop esi edx ebx eax
4042
			.c_next:
4043
			shr ah,1
4044
			dec al
4045
			jnz .cycle
4046
		;выход из узла
4047
		inc ecx
4048
		pop edx
4049
		jmp .end_f
4050
	.sub_trees:
4051
		cmp ecx,0
4052
		jl .end_0 ;не рисуем очень маленькие воксели
4053
 
4054
			;рисуем узел
4055
			mov eax,[edi]
4056
			and eax,0xffffff
4057
 
4058
			cmp ecx,1
4059
			jl @f
4060
				;квадрат больше текущего масштаба
4061
				stdcall vox_draw_square_1g, [buf_i],[buf_z],eax
4062
				jmp .end_0
4063
			@@:
4064
				;квадрат текущего масштаба
4065
				push ecx
4066
				mov ecx,eax
4067
				stdcall buf_get_pixel, [buf_z], ebx,edx
4068
				cmp eax,esi
4069
				jge .end_1
4070
				stdcall buf_set_pixel, [buf_i], ebx,edx,ecx
4071
				stdcall buf_set_pixel, [buf_z], ebx,edx,esi
4072
				.end_1:
4073
				pop ecx
4074
		.end_0:
4075
		add edi,4
4076
	.end_f:
4077
	ret
4078
endp
4079
 
4080
;output:
4081
; eax - разрушается
4082
align 4
4083
proc vox_draw_square_1g uses ecx edx edi, buf_i:dword, buf_z:dword, color:dword
4084
locals
4085
	img_size dd ?
4086
	coord_y dd ?
4087
endl
4088
	mov edi,[buf_z]
4089
	xor eax,eax
4090
	inc eax
4091
	shl eax,cl
4092
	mov [img_size],eax
4093
	mov [coord_y],eax
4094
	.cycle_0:
4095
	push ebx
4096
	mov ecx,[img_size]
4097
	cld
4098
	.cycle_1:
4099
		push ecx
4100
		mov ecx,edx
4101
		call get_pixel_32
4102
		pop ecx
4103
		cmp eax,esi
4104
		jge @f
4105
			stdcall buf_set_pixel, [buf_i], ebx,edx, [color]
4106
			stdcall buf_set_pixel, edi, ebx,edx, esi
4107
		@@:
4108
		inc ebx
4109
	loop .cycle_1
4110
	pop ebx
4111
	inc edx
4112
	dec dword[coord_y]
4113
	jnz .cycle_0
4114
	ret
4115
endp
4116
 
4117
;description:
4118
; функция рисующая воксельный объект (видно 3 грани)
4119
;input:
4120
; buf_i - буфер в котором рисуется (24 бита)
4121
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2758 IgorA 4122
; h_br - кисть с изображениями вокселей (32 бита)
4123
; v_obj - воксельный объект
4124
; k_scale - коэф. для масштабирования изображения
4125
align 4
4126
proc buf_vox_obj_draw_3g, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
4127
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword
4128
pushad
4129
	mov edi,[v_obj]
4130
	mov ecx,[k_scale]
4131
	mov ebx,[coord_x]
4132
	mov edx,[coord_y]
4133
	add edi,vox_offs_data
4134
	mov esi,[coord_z]
4135
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4136
popad
4137
	ret
4138
endp
4139
 
4140
;description:
4141
; функция рисующая часть воксельного объекта
4142
;input:
4143
; buf_i - буфер в котором рисуется (24 бита)
4144
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
4145
; h_br - кисть с изображениями вокселей (32 бита)
4146
; v_obj - воксельный объект
4147
; k_scale - коэф. для масштабирования изображения
4148
align 4
4149
proc buf_vox_obj_draw_3g_scaled, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
4150
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword,\
4151
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword,b_color:dword
4152
pushad
4153
locals
4154
	p_node dd 0 ;родительский узел
4155
endl
4156
	mov edi,[v_obj]
4157
	add edi,vox_offs_data
4158
 
4159
	mov ecx,[k_scale]
4160
	mov ebx,[coord_x]
4161
 
4162
	;тестовая рамка
4163
	mov eax,[h_br]
4164
 
4165
	movzx edx,byte[eax]
4166
	movzx esi,byte[eax+1]
4167
	cmp ecx,1
4168
	jl .end_c0
4169
		shl edx,cl
4170
		shl esi,cl
4171
	.end_c0:
4172
	;stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
4173
 
4174
	;вертикальная полоса
4175
	add ebx,edx
4176
	shr edx,cl
4177
	stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
4178
	mov ecx,[s_k_scale]
4179
	shr esi,cl
4180
	xor eax,eax
4181
	inc eax
4182
	shl eax,cl
4183
	dec eax
4184
	sub eax,[s_c_z] ;значения по оси z возрастают с низу вверх
4185
	imul eax,esi
4186
	add eax,[coord_y]
4187
	stdcall buf_filled_rect_by_size, [buf_i], ebx,eax,edx,esi, [b_color]
4188
	mov ebx,[coord_y]
4189
	shl esi,cl
4190
	add ebx,esi
4191
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
4192
	shr eax,1
4193
	mov esi,[h_br]
4194
	movzx esi,byte[esi+1]
4195
	;ползунок
4196
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,eax,esi, [s_c_x], [s_k_scale], [b_color]
4197
	mov edx,[coord_x]
4198
	add edx,eax
4199
	;ползунок
4200
	stdcall draw_polz_hor, [buf_i], edx,ebx,eax,esi, [s_c_y], [s_k_scale], [b_color]
4201
;---
4202
 
4203
	mov esi,[s_k_scale]
4204
	cmp esi,1
4205
	jl .end_2
4206
 
4207
	; *** (1) ***
4208
	.found:
4209
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
4210
	movzx bx,byte[edi+3]
4211
	mov [p_node],edi
4212
	add edi,4
4213
	cmp eax,0
4214
	je .end_1
4215
	mov ecx,eax
4216
	cld
4217
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
4218
		bt bx,0 ;проверяем есть ли дочерние узлы
4219
		jnc .end_0
4220
			xor eax,eax
4221
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
4222
		.end_0:
4223
		shr bx,1
4224
		loop @b
4225
	.end_1:
4226
	bt bx,0
4227
	jnc .end_2 ;если поддерева не существует
4228
	dec esi
4229
	cmp esi,0
4230
	jg .found
4231
 
4232
	; *** (2) ***
4233
	;рисование части объекта
4234
	mov ecx,[k_scale]
4235
	mov ebx,[coord_x]
4236
	mov edx,[coord_y]
4237
	mov esi,[coord_z]
4238
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4239
	.end_2:
4240
 
4241
popad
4242
	ret
4243
endp
4244
 
4245
;input:
4246
; h_br - кисть с изображениями вокселей (32 бита)
4247
; ebx - coord_x
4248
; edx - coord_y
4249
; esi - coord_z
4250
; ecx - уровень текушего узла
4251
; edi - указатель на данные воксельного объекта
4252
align 4
4253
proc vox_go_in_node, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword
4254
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4255
	je .sub_trees
4256
		;рекурсивный перебор поддеревьев
4257
		push eax edx
4258
 
4259
		;прорисовка рамки если размер узла = 1
4260
		cmp ecx,0
4261
		jne .end_2
4262
			push eax
4263
				stdcall vox_get_sub_brush,[h_br],0 ;определяем кисть для рисования
4264
				cmp eax,0 ;если кисть не найдена
4265
				je @f
4266
					stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
4267
				@@:
4268
			pop eax
4269
		.end_2:
4270
 
4271
		;вход внутрь узла
4272
		dec ecx
4273
;---
4274
		push ebx
4275
			;mov eax,(h-h_osn/2)
4276
			mov ebx,[h_br]
4277
			movzx eax,byte[ebx+1]
2975 IgorA 4278
			cmp byte[ebx+2],0
4279
			je @f
4280
				;если кисть с 3-мя гранями
4281
				movzx ebx,byte[ebx+2]
4282
				shr ebx,1
4283
				sub eax,ebx
4284
				jmp .end_0
4285
			@@:
4286
				;если кисть с 2-мя гранями
4287
				movzx ebx,byte[ebx]
4288
				shr ebx,1
4289
			.end_0:
2758 IgorA 4290
		cmp ecx,1
2975 IgorA 4291
		jl @f
2758 IgorA 4292
			shl eax,cl
4293
			shl ebx,cl
2975 IgorA 4294
		@@:
2758 IgorA 4295
		add esi,ebx
4296
		pop ebx
4297
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4298
;---
4299
		mov ah,byte[edi+3]
4300
		add edi,4
4301
		mov al,8
4302
		.cycle:
4303
			bt ax,8 ;тестируем только ah
4304
			jnc .c_next
4305
				push ebx edx esi
4306
				stdcall vox_corect_coords, [h_br], [v_obj]
4307
				stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4308
				pop esi edx ebx
4309
			.c_next:
4310
			shr ah,1
4311
			dec al
4312
			jnz .cycle
4313
 
4314
		;выход из узла
4315
		inc ecx
4316
		pop edx eax
4317
 
4318
		jmp .end_f
4319
	.sub_trees:
4320
		;рисуем узел
4321
		push eax
4322
			stdcall vox_get_sub_brush,[h_br],ecx ;определяем кисть для рисования
4323
			cmp eax,0 ;если кисть не найдена
4324
			je @f
4325
				stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
4326
			@@:
4327
		pop eax
4328
 
4329
		add edi,4
4330
	.end_f:
4331
	ret
4332
endp
4333
 
4334
;description:
4335
; функция рисующая одиночный воксел
4336
;input:
4337
; buf_i - буфер в котором рисуется (24 бита)
4338
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
4339
; buf_v - буфер с изображением вокселя (32 бита)
4340
; v_color - цвет
4341
align 4
4342
proc draw_vox, buf_i:dword, buf_z:dword, buf_v:dword,\
4343
coord_x:dword, coord_y:dword, coord_z:dword, v_color:dword
4344
pushad
4345
	mov eax,[coord_x]
4346
	mov ebx,[coord_y]
4347
	mov edi,[buf_v]
4348
	mov ecx,buf2d_h
4349
	mov esi,buf2d_w
4350
	imul ecx,esi
4351
	add esi,eax
4352
	mov edx,buf2d_data
4353
	cld
4354
	;ecx - count pixels in voxel
4355
	;edx - указатель на данные в воксельном буфере
4356
	;edi - указатель на воксельный буфер
4357
	;esi - width voxel buffer add coord x
4358
	.cycle:
4359
		cmp dword[edx],0
4360
		je @f
4361
			;проверяем буфер глубины
4362
			push eax
4363
			stdcall buf_get_pixel, [buf_z],eax,ebx
4364
			sub eax,[coord_z]
4365
			cmp eax,[edx]
4366
			jl .dr_pixel
4367
				pop eax
4368
				jmp @f
4369
			.dr_pixel:
4370
				;рисуем точку
4371
				pop eax
4372
				stdcall buf_set_pixel, [buf_i],eax,ebx,[v_color]
4373
				push ecx
4374
				mov ecx,[coord_z]
4375
				add ecx,[edx]
4376
				stdcall buf_set_pixel, [buf_z],eax,ebx,ecx
4377
				pop ecx
4378
		@@:
4379
		add edx,4
4380
		inc eax
4381
		cmp eax,esi
4382
		jl @f
4383
			inc ebx
4384
			sub eax,buf2d_w
4385
		@@:
4386
		loop .cycle
4387
popad
4388
	ret
4389
endp
4390
 
4391
;description:
4392
;функция для коректировки координат
4393
;направления осей координат в вокселе:
4394
;*z
4395
;|
4396
;+
4397
;  * y
4398
; /
4399
;+
4400
; \
4401
;  * x
4402
;input:
4403
;  al - номер узла в дереве (от 1 до 8)
4404
; ebx - координата x
4405
; edx - координата y
4406
; esi - координата z
4407
; ecx - уровень текушего узла
4408
;output:
4409
; ebx - новая координата x
4410
; edx - новая координата y
4411
; esi - новая координата z
4412
align 4
4413
proc vox_corect_coords, h_br:dword, v_obj:dword
4414
locals
4415
	osn_w_2 dd ? ;ширина основания единичного вокселя : 2
4416
	vox_h dd ? ;высота единичного вокселя
4417
endl
4418
	cmp ecx,0
4419
	jl .end_f ;для ускорения отрисовки
4420
 
4421
	push eax edi
4422
	and eax,15 ;выделяем номер узла в дереве
4423
	mov edi,[v_obj]
4424
	add edi,vox_offs_tree_table
4425
	add edi,8
4426
	sub edi,eax
4427
 
4428
	push ebx ecx
4429
		mov ebx,[h_br]
4430
 
4431
		movzx ecx,byte[ebx]
4432
		shr ecx,1
4433
		mov dword[osn_w_2],ecx
4434
 
4435
		movzx ecx,byte[ebx+2]
4436
		movzx ebx,byte[ebx+1]
4437
		sub ebx,ecx
4438
		mov dword[vox_h],ebx
4439
		shr ecx,1
4440
		mov eax,ecx ;eax - высота основания единичного вокселя : 2
4441
	pop ecx ebx
4442
 
4443
	cmp ecx,1
2975 IgorA 4444
	jl @f ;во избежание зацикливания
2758 IgorA 4445
		shl eax,cl
4446
		shl dword[osn_w_2],cl
4447
		shl dword[vox_h],cl
2975 IgorA 4448
	@@:
2758 IgorA 4449
 
4450
;	add esi,eax ;меняем глубину для буфера z (компенсация для координаты y)
4451
	bt word[edi],0 ;test voxel coord x
4452
	jnc @f
4453
		add ebx,[osn_w_2]
2975 IgorA 4454
		cmp eax,0
4455
		jne .end_0
4456
			add esi,[osn_w_2] ;меняем глубину для буфера z
4457
			jmp @f
4458
		.end_0:
2758 IgorA 4459
		add edx,eax
4460
		add esi,eax ;меняем глубину для буфера z
4461
	@@:
4462
	bt word[edi],1 ;test voxel coord y
4463
	jnc @f
4464
		add ebx,[osn_w_2]
2975 IgorA 4465
		cmp eax,0
4466
		jne .end_1
4467
			sub esi,[osn_w_2] ;меняем глубину для буфера z
4468
			jmp @f
4469
		.end_1:
2758 IgorA 4470
		sub edx,eax
4471
		sub esi,eax ;меняем глубину для буфера z
4472
	@@:
4473
	bt word[edi],2 ;test voxel coord z
4474
	jnc @f
4475
		sub edx,[vox_h]
4476
	@@:
4477
	pop edi eax
4478
	.end_f:
4479
	ret
4480
endp
4481
 
4482
;извлекаем из h_br указатель на буфер с изображением вокселя, указанного порядка n
4483
align 4
4484
proc vox_get_sub_brush uses ebx ecx, h_br:dword, n:dword
4485
	xor eax,eax
4486
	mov ebx,[n]
4487
	cmp ebx,0
4488
	jl @f
4489
	mov ecx,[h_br]
4490
	cmp bl,byte[ecx+3]
4491
	jg @f
4492
		add ecx,4
4493
		imul ebx,BUF_STRUCT_SIZE
4494
		mov eax,ebx
4495
		add eax,ecx
4496
	@@:
4497
	ret
4498
endp
4499
 
4500
;description:
4501
; функция рисующая срез воксельного обьекта
4502
;input:
4503
; v_size - размер квадрата с вокселем
4504
; k_scale - степень детализации изображения
4505
; n_plane - номер плоскости сечния (в пределах от 0 до 2^k_scale - 1)
4506
; b_color - цвет границы
4507
align 4
4508
proc buf_vox_obj_draw_pl, buf_i:dword, v_obj:dword, coord_x:dword,\
4509
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword
4510
	cmp [k_scale],0
4511
	jl .end_f
4512
pushad
4513
	mov eax,[v_size]
4514
	mov ecx,[k_scale]
4515
	mov ebx,eax
4516
	cmp ecx,1
4517
	jl @f
4518
		shl ebx,cl
4519
	@@:
4520
	;ebx - полный размер изображения
4521
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
4522
	mov edx,ebx
4523
	add ebx,[coord_y]
4524
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
4525
 
4526
	;рисование точек для сетки
4527
	push ecx
4528
	mov edi,1
4529
	cmp ecx,1
4530
	jl @f
4531
		shl edi,cl
4532
	@@:
4533
	dec edi
4534
	cmp edi,1
4535
	jl .end_0
4536
	mov ecx,edi
4537
	imul ecx,edi
4538
	mov ebx,[coord_x]
4539
	mov edx,[coord_y]
4540
	add edx,eax
4541
	xor esi,esi
4542
	cld
4543
	@@:
4544
		add ebx,eax
4545
		inc esi
4546
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
4547
		cmp esi,edi
4548
		jl .end_1
4549
			;переход точек на новую строку
4550
			xor esi,esi
4551
			mov ebx,[coord_x]
4552
			add edx,eax
4553
		.end_1:
4554
		loop @b
4555
	.end_0:
4556
	pop ecx
4557
 
4558
	;eax - размер одного квадрата
2815 IgorA 4559
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 4560
	mov ebx,[coord_x]
4561
	mov edx,[coord_y]
4562
	mov edi,[v_obj]
4563
	add edi,vox_offs_data
4564
	xor esi,esi
4565
	push eax
2815 IgorA 4566
	mov eax,1
4567
	shl eax,cl
4568
	dec eax
4569
	sub eax,[n_plane]
4570
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],eax
2758 IgorA 4571
popad
4572
	.end_f:
4573
	ret
4574
endp
4575
 
4576
;description:
4577
; функция рисующая срез части воксельного обьекта
4578
;input:
4579
; s_c_x, s_c_y, s_c_z, s_k_scale - параметры определяющие часть воксельного объекта, которая будет рисоваться
4580
align 4
4581
proc buf_vox_obj_draw_pl_scaled, buf_i:dword, v_obj:dword, coord_x:dword,\
4582
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword,\
4583
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword
4584
	cmp [k_scale],0
4585
	jl .end_f
4586
pushad
4587
locals
4588
	p_node dd 0 ;родительский узел
4589
endl
4590
	mov eax,[v_size]
4591
	mov ecx,[k_scale]
4592
	mov ebx,eax
4593
	cmp ecx,1
4594
	jl @f
4595
		shl ebx,cl
4596
	@@:
4597
	;ebx - полный размер изображения
4598
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
4599
	mov edx,ebx
4600
	add ebx,[coord_y]
4601
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
4602
 
4603
	;рисование точек для сетки
4604
	push ecx
4605
	mov edi,1
4606
	cmp ecx,1
4607
	jl @f
4608
		shl edi,cl
4609
	@@:
4610
	dec edi
4611
	cmp edi,1
4612
	jl .end_3
4613
	mov ecx,edi
4614
	imul ecx,edi
4615
	mov ebx,[coord_x]
4616
	mov edx,[coord_y]
4617
	add edx,eax
4618
	xor esi,esi
4619
	cld
4620
	@@:
4621
		add ebx,eax
4622
		inc esi
4623
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
4624
		cmp esi,edi
4625
		jl .end_4
4626
			;переход точек на новую строку
4627
			xor esi,esi
4628
			mov ebx,[coord_x]
4629
			add edx,eax
4630
		.end_4:
4631
		loop @b
4632
	.end_3:
4633
	pop ecx
4634
 
4635
	mov esi,[s_k_scale]
4636
	cmp esi,1
4637
	jl .end_2
4638
	mov edi,[v_obj]
4639
	add edi,vox_offs_data
4640
 
4641
	; *** (1) ***
4642
	.found:
4643
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
4644
	movzx bx,byte[edi+3]
4645
	mov [p_node],edi
4646
	add edi,4
4647
	cmp eax,0
4648
	je .end_1
4649
	mov ecx,eax
4650
	cld
4651
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
4652
		bt bx,0 ;проверяем есть ли дочерние узлы
4653
		jnc .end_0
4654
			xor eax,eax
4655
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
4656
		.end_0:
4657
		shr bx,1
4658
		loop @b
4659
	.end_1:
4660
	bt bx,0
4661
	jnc .end_2 ;если поддерева не существует
4662
	dec esi
4663
	cmp esi,0
4664
	jg .found
4665
 
4666
	mov eax,[v_size]
4667
	;eax - размер одного квадрата
2815 IgorA 4668
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 4669
	mov ecx,[k_scale]
4670
	mov ebx,[coord_x]
4671
	mov edx,[coord_y]
4672
	xor esi,esi
4673
	push eax
2815 IgorA 4674
	mov eax,1
4675
	shl eax,cl
4676
	dec eax
4677
	sub eax,[n_plane]
2758 IgorA 4678
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj], eax
4679
 
4680
	.end_2:
4681
popad
4682
	.end_f:
4683
	ret
4684
endp
4685
 
4686
;description:
4687
; определение позиции узла в дереве (от 0 до 7)
4688
align 4
4689
proc vox_obj_get_node_position uses ebx ecx edi, v_obj:dword,\
4690
coord_x:dword,coord_y:dword,coord_z:dword,k_scale:dword
4691
	mov ecx,[k_scale]
4692
	dec ecx
4693
	mov eax,[coord_x]
4694
	mov ebx,[coord_y]
4695
	mov edi,[coord_z]
4696
	cmp ecx,1
4697
	jl .end_0
4698
		shr eax,cl
4699
		shr ebx,cl
4700
		shr edi,cl
4701
	.end_0:
4702
	and eax,1
4703
	bt ebx,0
4704
	jnc @f
4705
		bts eax,1
4706
	@@:
4707
	bt edi,0
4708
	jnc @f
4709
		bts eax,2
4710
	@@:
4711
 
4712
	mov edi,[v_obj]
4713
	add edi,vox_offs_tree_table
4714
	@@:
4715
		cmp al,byte[edi]
4716
		je @f
4717
		inc edi
4718
		jmp @b
4719
	@@:
4720
	sub edi,[v_obj]
4721
	sub edi,vox_offs_tree_table
4722
	mov eax,edi
4723
 
4724
	ret
4725
endp
4726
 
4727
;input:
4728
; edi - указатель на данные воксельного объекта
4729
;output:
4730
; eax - eax + число узлов в данных вокс. объекта
4731
; edi - указатель на смещенные данные вокс. объекта
4732
align 4
4733
proc vox_obj_rec0
4734
	inc eax
4735
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4736
	je .sub_trees
4737
 
4738
		;рекурсивный перебор поддеревьев
4739
		push ebx ecx
4740
		mov bh,byte[edi+3]
4741
		add edi,4
4742
		mov bl,8
4743
		.cycle:
4744
			bt bx,8 ;тестируем только bh
4745
			jnc .c_next
4746
				stdcall vox_obj_rec0
4747
			.c_next:
4748
			shr bh,1
4749
			dec bl
4750
			jnz .cycle
4751
		pop ecx ebx
4752
 
4753
		jmp .end_f
4754
	.sub_trees:
4755
		add edi,4
4756
	.end_f:
4757
	ret
4758
endp
4759
 
4760
;description:
4761
; функция рисующая горизонтальную полосу с ползунком
4762
align 4
4763
proc draw_polz_hor uses eax ebx ecx, buf:dword, coord_x:dword, coord_y:dword,\
4764
size_x:dword, size_y:dword, pos:dword, k_scale:dword, color:dword
4765
	mov ebx,[size_x]
4766
	stdcall buf_rect_by_size, [buf], [coord_x],[coord_y],ebx,[size_y], [color]
4767
	mov ecx,[k_scale]
4768
	shr ebx,cl
4769
	mov eax,[pos]
4770
	imul eax,ebx
4771
	add eax,[coord_x]
4772
	stdcall buf_filled_rect_by_size, [buf], eax,[coord_y],ebx,[size_y], [color]
4773
	ret
4774
endp
4775
 
4776
;input:
4777
; ebx - coord_x
4778
; edx - coord_y
4779
; esi - coord_z
4780
; ecx - уровень текушего узла
4781
; edi - указатель на данные воксельного объекта
4782
align 4
4783
proc draw_sub_vox_obj_pl, buf_i:dword, v_obj:dword, clip_z:dword,\
4784
v_size:dword
4785
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4786
	je .sub_trees
4787
 
4788
		;прорисовка рамки если размер узла = 1
4789
		cmp ecx,0
4790
		jne @f
2815 IgorA 4791
			;проверка глубины esi
4792
			;clip_z=n_plane
4793
			stdcall vox_is_clip, [clip_z];,[v_size]
4794
			cmp eax,0
4795
			je @f
4796
				push ecx
4797
				mov ecx,dword[edi]
4798
				and ecx,0xffffff
4799
				stdcall buf_rect_by_size, [buf_i], ebx,edx, [v_size],[v_size],ecx
4800
				pop ecx
2758 IgorA 4801
		@@:
4802
 
4803
		;рекурсивный перебор поддеревьев
4804
		push edx
4805
		;вход внутрь узла
4806
		dec ecx
4807
 
4808
		mov eax,[v_size]
4809
		cmp ecx,1
4810
		jl @f
4811
			shl eax,cl
4812
		@@:
2815 IgorA 4813
 
2758 IgorA 4814
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4815
 
4816
		mov ah,byte[edi+3]
4817
		add edi,4
4818
		mov al,8
4819
		.cycle:
4820
			bt ax,8 ;тестируем только ah
4821
			jnc .c_next
4822
				push eax ebx edx esi
4823
				stdcall vox_corect_coords_pl, [v_obj],[v_size]
4824
				stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],[clip_z],[v_size]
4825
				pop esi edx ebx eax
4826
			.c_next:
4827
			shr ah,1
4828
			dec al
4829
			jnz .cycle
4830
		;выход из узла
4831
		inc ecx
4832
		pop edx
4833
		jmp .end_f
4834
	.sub_trees:
4835
		cmp ecx,0
4836
		jl .end_0 ;не рисуем очень маленькие воксели
4837
 
2815 IgorA 4838
			;проверка глубины esi
4839
			;clip_z=n_plane
4840
			stdcall vox_is_clip, [clip_z]
4841
			cmp eax,0
4842
			je .end_0
2758 IgorA 4843
 
2815 IgorA 4844
			;рисуем узел
4845
			mov eax,[edi]
4846
			and eax,0xffffff
4847
			push eax ;цвет узла
2758 IgorA 4848
 
2815 IgorA 4849
			mov eax,[v_size]
4850
			cmp ecx,1
4851
			jl @f
4852
				;квадрат больше текущего масштаба
4853
				shl eax,cl ;размер узла
4854
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
4855
				push ebx edx esi
4856
				mov esi,eax
4857
				inc ebx
4858
				inc edx
4859
				sub esi,2
4860
				mov eax,[buf_i]
4861
				push dword 128
4862
				push dword[eax+16] ;+16 - b_color
4863
				stdcall combine_colors_3,[edi]
4864
				stdcall buf_rect_by_size, [buf_i], ebx,edx, esi,esi,eax
4865
				pop esi edx ebx
4866
				jmp .end_0
4867
			@@:
4868
				;квадрат текущего масштаба
4869
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
2758 IgorA 4870
		.end_0:
4871
		add edi,4
4872
	.end_f:
4873
	ret
4874
endp
4875
 
4876
;description:
4877
; вспомогательная функция для проверки глубины esi
4878
;input:
4879
; ecx - уровень текушего узла
4880
; esi - coord z
2815 IgorA 4881
; clip_z - n_plane
2758 IgorA 4882
;output:
4883
; eax - 0 if no draw, 1 if draw
4884
align 4
2815 IgorA 4885
proc vox_is_clip uses ebx edi, clip_z:dword
2758 IgorA 4886
	xor eax,eax
4887
	mov ebx,[clip_z]
2815 IgorA 4888
	mov edi,1
2758 IgorA 4889
	cmp ecx,1
4890
	jl @f
4891
		shl edi,cl
4892
	@@:
4893
	;edi = 2^ecx
4894
	add edi,esi
2815 IgorA 4895
	cmp edi,ebx ;if (esi+2^ecx <= n_plane) no draw
2758 IgorA 4896
	jle @f
2815 IgorA 4897
	inc ebx
4898
	cmp esi,ebx ;if (esi >= (n_plane+1)) no draw
2758 IgorA 4899
	jge @f
4900
		inc eax
4901
	@@:
4902
	ret
4903
endp
4904
 
4905
;функция для коректировки координат
4906
;направления осей координат в вокселе:
4907
;*z
4908
;|
4909
;+-* x
4910
;input:
4911
;  al - номер узла в дереве (от 1 до 8)
4912
; ebx - координата x
4913
; edx - координата y
4914
; esi - координата z
4915
; ecx - уровень текушего узла
4916
;output:
4917
; ebx - новая координата x
4918
; edx - новая координата y
4919
; esi - новая координата z
4920
align 4
4921
proc vox_corect_coords_pl, v_obj:dword, v_size:dword
4922
	cmp ecx,0
4923
	jl .end_f ;для ускорения отрисовки
4924
 
4925
	push eax edi
4926
	and eax,15 ;выделяем номер узла в дереве
4927
	mov edi,[v_obj]
4928
	add edi,vox_offs_tree_table
4929
	add edi,8
4930
	sub edi,eax
4931
 
2815 IgorA 4932
	mov eax,[v_size]
2758 IgorA 4933
	cmp ecx,1
2815 IgorA 4934
	jl @f
2758 IgorA 4935
		shl eax,cl
4936
	@@:
4937
 
4938
	bt word[edi],0 ;test voxel coord x
4939
	jnc @f
4940
		add ebx,eax
4941
	@@:
4942
	bt word[edi],2 ;test voxel coord z
4943
	jnc @f
4944
		sub edx,eax
4945
	@@:
2815 IgorA 4946
	bt word[edi],1 ;test voxel coord y
4947
	jc @f
4948
		mov eax,1
4949
		cmp ecx,1
4950
		jl .end_0
4951
			shl eax,cl
4952
		.end_0:
4953
		add esi,eax ;меняем глубину для буфера z
4954
	@@:
2758 IgorA 4955
	pop edi eax
4956
	.end_f:
4957
	ret
4958
endp
4959
 
4960
;description:
4961
; функция рисующая тени
4962
;input:
4963
; buf_i - буфер в котором рисуется (24 бита)
4964
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
4965
; h_br - кисть с изображениями вокселей (32 бита)
4966
; k_scale - коэф. для масштабирования изображения
4967
align 4
4968
proc buf_vox_obj_draw_3g_shadows, buf_i:dword, buf_z:dword, h_br:dword, \
4969
coord_x:dword, coord_y:dword, color:dword, k_scale:dword, prop:dword
4970
locals
4971
	correct_z dd 0 ;коректировка для буфера глубины
4972
endl
4973
pushad
4974
	mov eax,[k_scale]
4975
	add eax,[prop]
4976
	mov dword[correct_z],8
4977
	sub [correct_z],eax
4978
	mov ebx,[coord_x]
4979
	;correct_z = 8-k_scale-prop
4980
 
4981
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
4982
	mov edx,eax ;edx - ширина изображения
4983
	stdcall buf_vox_obj_get_img_h_3g, [h_br],[k_scale]
4984
	mov esi,eax
4985
 
4986
	mov edi,[coord_y]
4987
	mov ecx,edx
4988
	add edx,ebx ;ширина + отступ слева
4989
	imul ecx,esi
4990
	cld
4991
	.cycle_0:
4992
		stdcall buf_get_pixel, [buf_z],ebx,edi
4993
		cmp eax,0
4994
		je @f
4995
			stdcall vox_correct_z, [correct_z]
4996
			push eax
4997
			stdcall buf_get_pixel, [buf_i],ebx,edi
4998
			stdcall combine_colors_3,eax,[color] ;,eax
4999
			stdcall buf_set_pixel, [buf_i],ebx,edi,eax
5000
		@@:
5001
		inc ebx
5002
		cmp ebx,edx
5003
		jl @f
5004
			mov ebx,[coord_x]
5005
			inc edi
5006
		@@:
5007
		loop .cycle_0
5008
 
5009
popad
5010
	ret
5011
endp
5012
 
5013
;output:
5014
; eax - scaled coord z
5015
align 4
5016
proc vox_correct_z uses ecx, correct_z:dword
5017
	mov ecx,[correct_z]
5018
	cmp ecx,0
5019
	je .end_f
5020
	jl .end_0
5021
		shl eax,cl
5022
		jmp .end_f
5023
	.end_0:
5024
		neg ecx
5025
		inc ecx
5026
		shr eax,cl
5027
	.end_f:
5028
	ret
5029
endp
5030
 
5031
;output:
5032
; eax - color
5033
align 4
5034
proc combine_colors_3 uses ebx ecx edx edi esi, col_0:dword, col_1:dword, alpha:dword
5035
 
5036
	mov ebx,[col_0]
5037
	mov ecx,[col_1]
5038
	movzx di,byte[alpha] ;pro
5039
	mov si,0x00ff ;---get transparent---
5040
	sub si,di ;256-pro
5041
 
5042
	;---blye---
5043
	movzx ax,bl
5044
	imul ax,si
5045
	movzx dx,cl
5046
	imul dx,di
5047
	add ax,dx
5048
	mov cl,ah
5049
	;---green---
5050
	movzx ax,bh
5051
	imul ax,si
5052
	movzx dx,ch
5053
	imul dx,di
5054
	add ax,dx
5055
	mov ch,ah
5056
	shr ebx,16
5057
	ror ecx,16
5058
	;---red---
5059
	movzx ax,bl
5060
	imul ax,si
5061
	movzx dx,cl
5062
	imul dx,di
5063
	add ax,dx
5064
 
5065
	shl eax,8
5066
	ror ecx,16
5067
	mov ax,cx
5068
	and eax,0xffffff
5069
 
5070
	ret
5071
endp
5072
 
1535 IgorA 5073
txt_err_n8b db 'need buffer 8 bit',13,10,0
5074
txt_err_n24b db 'need buffer 24 bit',13,10,0
2815 IgorA 5075
txt_err_n32b db 'need buffer 32 bit',13,10,0
2358 IgorA 5076
txt_err_n8_24b db 'need buffer 8 or 24 bit',13,10,0
1535 IgorA 5077
 
5078
align 16
5079
EXPORTS:
5080
	dd sz_lib_init, lib_init
5081
	dd sz_buf2d_create, buf_create
5082
	dd sz_buf2d_create_f_img, buf_create_f_img
5083
	dd sz_buf2d_clear, buf_clear
5084
	dd sz_buf2d_draw, buf_draw_buf
5085
	dd sz_buf2d_delete, buf_delete
2136 IgorA 5086
	dd sz_buf2d_resize, buf_resize
2975 IgorA 5087
	dd sz_buf2d_rotate, buf_rotate
1535 IgorA 5088
	dd sz_buf2d_line, buf_line_brs
2230 IgorA 5089
	dd sz_buf2d_line_sm, buf_line_brs_sm
1634 IgorA 5090
	dd sz_buf2d_rect_by_size, buf_rect_by_size
1642 IgorA 5091
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
1535 IgorA 5092
	dd sz_buf2d_circle, buf_circle
5093
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
5094
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
5095
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
5096
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
5097
	dd sz_buf2d_bit_blt, buf_bit_blt
5098
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
5099
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1727 IgorA 5100
	dd sz_buf2d_curve_bezier, buf_curve_bezier
1535 IgorA 5101
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
5102
	dd sz_buf2d_draw_text, buf_draw_text
5103
	dd sz_buf2d_crop_color, buf_crop_color
5104
	dd sz_buf2d_offset_h, buf_offset_h
1684 IgorA 5105
	dd sz_buf2d_flood_fill, buf_flood_fill
1910 IgorA 5106
	dd sz_buf2d_set_pixel, buf_set_pixel
2658 IgorA 5107
	dd sz_buf2d_get_pixel, buf_get_pixel
3040 IgorA 5108
	dd sz_buf2d_flip_v, buf_flip_v
3105 IgorA 5109
	dd sz_buf2d_filter_dither, buf_filter_dither
2748 IgorA 5110
	dd sz_buf2d_vox_brush_create, vox_brush_create
5111
	dd sz_buf2d_vox_brush_delete, vox_brush_delete
2758 IgorA 5112
	dd sz_buf2d_vox_obj_get_img_w_3g, buf_vox_obj_get_img_w_3g
5113
	dd sz_buf2d_vox_obj_get_img_h_3g, buf_vox_obj_get_img_h_3g
2815 IgorA 5114
	dd sz_buf2d_vox_obj_draw_1g, buf_vox_obj_draw_1g
2758 IgorA 5115
	dd sz_buf2d_vox_obj_draw_3g, buf_vox_obj_draw_3g
5116
	dd sz_buf2d_vox_obj_draw_3g_scaled, buf_vox_obj_draw_3g_scaled
5117
	dd sz_buf2d_vox_obj_draw_pl, buf_vox_obj_draw_pl
5118
	dd sz_buf2d_vox_obj_draw_pl_scaled, buf_vox_obj_draw_pl_scaled
5119
	dd sz_buf2d_vox_obj_draw_3g_shadows, buf_vox_obj_draw_3g_shadows
1535 IgorA 5120
	dd 0,0
5121
	sz_lib_init db 'lib_init',0
5122
	sz_buf2d_create db 'buf2d_create',0
5123
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
5124
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
5125
	sz_buf2d_draw db 'buf2d_draw',0
5126
	sz_buf2d_delete db 'buf2d_delete',0
2136 IgorA 5127
	sz_buf2d_resize db 'buf2d_resize',0
2975 IgorA 5128
	sz_buf2d_rotate db 'buf2d_rotate',0
1535 IgorA 5129
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
2230 IgorA 5130
	sz_buf2d_line_sm db 'buf2d_line_sm',0 ;рисование сглаженной линии
1642 IgorA 5131
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;рисование рамки прямоугольника, 2-я координата задана по размеру
5132
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;рисование залитого прямоугольника, 2-я координата задана по размеру
1535 IgorA 5133
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
5134
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
5135
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
5136
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
5137
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
5138
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
5139
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
5140
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1727 IgorA 5141
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
1535 IgorA 5142
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
5143
	sz_buf2d_draw_text db 'buf2d_draw_text',0
5144
	sz_buf2d_crop_color db 'buf2d_crop_color',0
5145
	sz_buf2d_offset_h db 'buf2d_offset_h',0
1684 IgorA 5146
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
1910 IgorA 5147
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
2658 IgorA 5148
	sz_buf2d_get_pixel db 'buf2d_get_pixel',0
3040 IgorA 5149
	sz_buf2d_flip_v db 'buf2d_flip_v',0
3105 IgorA 5150
	sz_buf2d_filter_dither db 'buf2d_filter_dither',0
2748 IgorA 5151
	sz_buf2d_vox_brush_create db 'buf2d_vox_brush_create',0
5152
	sz_buf2d_vox_brush_delete db 'buf2d_vox_brush_delete',0
2758 IgorA 5153
	sz_buf2d_vox_obj_get_img_w_3g db 'buf2d_vox_obj_get_img_w_3g',0
5154
	sz_buf2d_vox_obj_get_img_h_3g db 'buf2d_vox_obj_get_img_h_3g',0
2815 IgorA 5155
	sz_buf2d_vox_obj_draw_1g db 'buf2d_vox_obj_draw_1g',0
2758 IgorA 5156
	sz_buf2d_vox_obj_draw_3g db 'buf2d_vox_obj_draw_3g',0
5157
	sz_buf2d_vox_obj_draw_3g_scaled db 'buf2d_vox_obj_draw_3g_scaled',0
5158
	sz_buf2d_vox_obj_draw_pl db 'buf2d_vox_obj_draw_pl',0
5159
	sz_buf2d_vox_obj_draw_pl_scaled db 'buf2d_vox_obj_draw_pl_scaled',0
5160
	sz_buf2d_vox_obj_draw_3g_shadows db 'buf2d_vox_obj_draw_3g_shadows',0