Subversion Repositories Kolibri OS

Rev

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