Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1535 IgorA 1
format MS COFF
2
public EXPORTS
3
section '.flat' code readable align 16
4
 
5
include '../../../../macros.inc'
6
include '../../../../proc32.inc'
7
 
8
;-----------------------------------------------------------------------------
9
mem.alloc   dd ? ;функция для выделения памяти
10
mem.free    dd ? ;функция для освобождения памяти
11
mem.realloc dd ? ;функция для перераспределения памяти
12
dll.load    dd ?
13
 
14
BUF_STRUCT_SIZE equ 21
15
buf2d_data equ dword[edi] ;данные буфера изображения
16
buf2d_w equ dword[edi+8] ;ширина буфера
17
buf2d_h equ dword[edi+12] ;высота буфера
1538 IgorA 18
buf2d_l equ word[edi+4]
1535 IgorA 19
buf2d_t equ word[edi+6] ;отступ сверху
20
buf2d_size_lt equ dword[edi+4] ;отступ слева и справа для буфера
21
buf2d_color equ dword[edi+16] ;цвет фона буфера
22
buf2d_bits equ byte[edi+20] ;количество бит в 1-й точке изображения
23
 
24
struct buf_2d_header
25
	img_data dd ?
26
	left dw ? ;+4 left
27
	top dw ? ;+6 top
28
	size_x dd ? ;+8 w
29
	size_y dd ? ;+12 h
30
	color dd ? ;+16 color
31
	bit_pp db ? ;+21 bit in pixel
32
ends
33
 
34
macro swap v1, v2 {
35
  push v1
36
  push v2
37
  pop v1
38
  pop v2
39
}
40
 
41
;флаги, для функции обрезания буфера
42
BUF2D_OPT_CROP_TOP equ 1 ;обрезка сверху
43
BUF2D_OPT_CROP_LEFT equ 2 ;обрезка слева
44
BUF2D_OPT_CROP_BOTTOM equ 4 ;обрезка снизу
45
BUF2D_OPT_CROP_RIGHT equ 8 ;обрезка справа
46
BUF2D_BIT_OPT_CROP_TOP equ 0
47
BUF2D_BIT_OPT_CROP_LEFT equ 1
48
BUF2D_BIT_OPT_CROP_BOTTOM equ 2
49
BUF2D_BIT_OPT_CROP_RIGHT equ 3
50
 
2748 IgorA 51
vox_offs_tree_table equ 4
52
vox_offs_data equ 12
53
 
1535 IgorA 54
;input:
55
; eax = указатель на функцию выделения памяти
56
; ebx = ... освобождения памяти
57
; ecx = ... перераспределения памяти
58
; edx = ... загрузки библиотеки (пока не используется)
59
align 16
60
lib_init:
61
	mov dword[mem.alloc], eax
62
	mov dword[mem.free], ebx
63
	mov dword[mem.realloc], ecx
64
	mov dword[dll.load], edx
65
	ret
66
 
67
;input:
68
; ebx = coord x
69
; ecx = coord y
70
; edx = pixel color
71
; edi = pointer to buffer struct
72
align 4
73
draw_pixel:
74
	;cmp buf2d_bits,24
75
	;jne @f
76
	bt ebx,31
77
	jc @f
78
	bt ecx,31
79
	jc @f
80
	cmp ebx,buf2d_w
81
	jge @f
82
	cmp ecx,buf2d_h
83
	jge @f
84
	push esi
85
		mov esi,buf2d_w ;size x
86
		imul esi,ecx ;size_x*y
87
		add esi,ebx	 ;size_x*y+x
2358 IgorA 88
		cmp buf2d_bits,8
89
		je .beg8
2658 IgorA 90
		cmp buf2d_bits,32
91
		je .beg32
2358 IgorA 92
			lea esi,[esi+esi*2] ;(size_x*y+x)*3
93
			add esi,buf2d_data  ;ptr+(size_x*y+x)*3
94
			mov word[esi],dx ;copy pixel color
95
			ror edx,16
96
			mov byte[esi+2],dl
97
			ror edx,16
98
			jmp .end_draw
99
		.beg8: ;рисование точки в 8 битном буфере
100
			add esi,buf2d_data  ;ptr+(size_x*y+x)
101
			mov byte[esi],dl
2658 IgorA 102
			jmp .end_draw
103
		.beg32: ;рисование точки в 32 битном буфере
104
			shl esi,2
105
			add esi,buf2d_data  ;ptr+(size_x*y+x)
106
			mov dword[esi],edx
2358 IgorA 107
		.end_draw:
1535 IgorA 108
	pop esi
109
	@@:
110
	ret
111
 
1684 IgorA 112
;input:
113
; ebx = coord x
114
; ecx = coord y
115
; edi = pointer to buffer struct
116
;output:
117
; eax = цвет точки
118
; в случае ошибки eax = 0xffffffff
119
align 4
2658 IgorA 120
get_pixel_8:
121
	mov eax,0xffffffff
122
 
123
	bt ebx,31
124
	jc @f
125
	bt ecx,31
126
	jc @f
127
	cmp ebx,buf2d_w
128
	jge @f
129
	cmp ecx,buf2d_h
130
	jge @f
131
	push esi
132
		mov esi,buf2d_w ;size x
133
		imul esi,ecx ;size_x*y
134
		add esi,ebx	 ;size_x*y+x
135
		add esi,buf2d_data  ;ptr+(size_x*y+x)
136
 
137
		movzx eax,byte[esi] ;copy pixel color
138
	pop esi
139
	@@:
140
	ret
141
 
142
;input:
143
; ebx = coord x
144
; ecx = coord y
145
; edi = pointer to buffer struct
146
;output:
147
; eax = цвет точки
148
; в случае ошибки eax = 0xffffffff
149
align 4
1684 IgorA 150
get_pixel_24:
151
	mov eax,0xffffffff
152
 
153
	bt ebx,31
154
	jc @f
155
	bt ecx,31
156
	jc @f
157
	cmp ebx,buf2d_w
158
	jge @f
159
	cmp ecx,buf2d_h
160
	jge @f
161
	push esi
162
		mov esi,buf2d_w ;size x
163
		imul esi,ecx ;size_x*y
164
		add esi,ebx	 ;size_x*y+x
165
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
166
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
167
 
168
		xor eax,eax
169
		mov ax,word[esi] ;copy pixel color
170
		ror eax,16
171
		mov al,byte[esi+2]
172
		ror eax,16
173
	pop esi
174
	@@:
175
	ret
176
 
2230 IgorA 177
;input:
178
; ebx = coord x
179
; ecx = coord y
2658 IgorA 180
; edi = pointer to buffer struct
181
;output:
182
; eax = цвет точки
183
; в случае ошибки eax = 0xffffffff
184
align 4
185
get_pixel_32:
186
	mov eax,0xffffffff
187
 
188
	bt ebx,31
189
	jc @f
190
	bt ecx,31
191
	jc @f
192
	cmp ebx,buf2d_w
193
	jge @f
194
	cmp ecx,buf2d_h
195
	jge @f
196
	push esi
197
		mov esi,buf2d_w ;size x
198
		imul esi,ecx ;size_x*y
199
		add esi,ebx	 ;size_x*y+x
200
		shl esi,2
201
		add esi,buf2d_data  ;ptr+(size_x*y+x)*4
202
 
203
		mov eax,dword[esi] ;copy pixel color
204
	pop esi
205
	@@:
206
	ret
207
 
208
;input:
209
; ebx = coord x
210
; ecx = coord y
2230 IgorA 211
; edx = pixel color + transparent
212
; edi = pointer to buffer struct
213
; t_prop, m_prop - коэфициенты необходимые для вычисления степени прозрачности
214
align 4
215
transp_32 dd 0 ;цвет рисуемой точки + прозрачность
216
align 4
217
proc draw_pixel_transp, t_prop:dword, m_prop:dword
218
	;cmp buf2d_bits,24
219
	;jne @f
220
	bt ebx,31
221
	jc @f
222
	bt ecx,31
223
	jc @f
224
	cmp ebx,buf2d_w
225
	jge @f
226
	cmp ecx,buf2d_h
227
	jge @f
228
	push eax ebx edx edi esi
229
		mov esi,buf2d_w ;size x
230
		imul esi,ecx ;size_x*y
231
		add esi,ebx	 ;size_x*y+x
232
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
233
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
1684 IgorA 234
 
2230 IgorA 235
		mov edi,esi ;указатель на цвет фона
236
		mov dword[transp_32],edx ;цвет рисуемой точки
237
 
238
		xor edx,edx
239
		mov eax,[t_prop]
240
		shl eax,8 ;*=256
241
		mov ebx,[m_prop]
242
		div ebx ;вычисляем коэф. прозрачности (должен быть от 0 до 255)
243
		bt ax,8
244
		jnc .over_255
245
			;если коеф. прозрачности >=256 то уменьшаем его до 255
246
			mov al,0xff
247
		.over_255:
248
 
249
		mov byte[transp_32+3],al ;прозрачность рисуемой точки
250
		mov esi,dword transp_32 ;указатель на цвет рисуемой точки
251
 
2920 IgorA 252
		call combine_colors_0
2230 IgorA 253
	pop esi edi edx ebx eax
254
	@@:
255
	ret
256
endp
257
 
1535 IgorA 258
;создание буфера
259
align 4
260
proc buf_create, buf_struc:dword
261
	pushad
262
	mov edi,dword[buf_struc]
263
	mov ecx,buf2d_w
264
	mov ebx,buf2d_h
265
	imul ecx,ebx
266
	cmp buf2d_bits,24
267
	jne @f
268
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
269
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
270
	@@:
271
	cmp buf2d_bits,32
272
	jne @f
273
		shl ecx,2 ; 32 bit = 4
274
	@@:
275
	invoke mem.alloc,ecx
276
	mov buf2d_data,eax
277
 
278
	stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
279
	popad
280
	ret
281
endp
282
 
283
;создание буфера на основе изображения rgb
284
align 4
285
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
286
	pushad
287
	mov edi,dword[buf_struc]
288
	mov ecx,buf2d_w
289
	mov ebx,buf2d_h
290
	imul ecx,ebx
291
	cmp buf2d_bits,24
292
	jne @f
293
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
294
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
295
	@@:
296
	cmp buf2d_bits,32
297
	jne @f
298
		shl ecx,2 ; 32 bit = 4
299
	@@:
300
	invoke mem.alloc,ecx
301
	mov buf2d_data,eax
302
 
303
	cmp buf2d_bits,24
304
	jne @f
305
		cld
306
		mov esi,[rgb_data]
307
		mov edi,eax ;eax=buf2d_data
308
		rep movsb ;копируем биты изображения в буфер
309
		jmp .end_create
310
	@@:
311
		stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
312
	.end_create:
313
	popad
314
	ret
315
endp
316
 
317
align 4
318
proc buf_clear, buf_struc:dword, color:dword ;очистка буфера заданым цветом
319
	pushad
320
	mov edi,dword[buf_struc]
321
 
322
	mov ecx,buf2d_w
323
	mov ebx,buf2d_h
324
	imul ecx,ebx
325
 
326
	cld
327
 
328
	cmp buf2d_bits,8
329
	jne .end_clear_8
330
		mov edi,buf2d_data
331
		mov al,byte[color]
332
		rep stosb
333
		jmp .end_clear_32
334
	.end_clear_8:
335
 
336
	cmp buf2d_bits,24
337
	jne .end_clear_24
338
		mov edi,buf2d_data
339
		mov eax,dword[color]
340
		mov ebx,eax
341
		shr ebx,16
342
		@@:
343
			stosw
344
			mov byte[edi],bl
345
			inc edi
346
			loop @b
347
		jmp .end_clear_32
348
	.end_clear_24:
349
 
350
	cmp buf2d_bits,32
351
	jne .end_clear_32
352
		mov edi,buf2d_data
353
		mov eax,dword[color]
354
		rep stosd
355
		;jmp .end_clear_32
356
	.end_clear_32:
357
	popad
358
	ret
359
endp
360
 
1538 IgorA 361
;функция для обрезания буферов 8 и 24 битных, по заданому цвету.
362
;параметр opt задается комбинацией констант:
363
; BUF2D_OPT_CROP_TOP - обрезка сверху
364
; BUF2D_OPT_CROP_LEFT - обрезка слева
365
; BUF2D_OPT_CROP_BOTTOM - обрезка снизу
366
; BUF2D_OPT_CROP_RIGHT - обрезка справа
1535 IgorA 367
align 4
1538 IgorA 368
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
1535 IgorA 369
locals
370
	crop_r dd ?
371
endl
372
	pushad
373
	mov edi,dword[buf_struc]
374
	cmp buf2d_bits,24
375
	jne .24end_f
376
 
377
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
378
	jae .24no_crop_bottom
379
		mov eax,dword[color]
380
		mov edx,eax ;ax = colors - r,g
381
		shr edx,16 ;dl = color - b
382
		mov ecx,buf2d_h
1555 IgorA 383
		cmp ecx,1
384
		jle .24no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 385
		mov ebx,buf2d_w
386
		imul ecx,ebx
387
		lea esi,[ecx+ecx*2] ;esi=3*ecx
388
		add esi,buf2d_data
389
		cld
390
		@@:
391
			sub esi,3
392
			cmp word[esi],ax
393
			jne @f
394
			cmp byte[esi+2],dl
395
			jne @f
396
			loop @b
397
		@@:
398
		lea ebx,[ebx+ebx*2]
399
		xor edx,edx
400
		mov eax,buf2d_h
401
		imul eax,ebx
402
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
403
		@@:
404
			add esi,ebx
405
			cmp esi,eax
406
			jge @f
407
			inc edx ;вычисляем число полных строк для обрезания
408
			loop @b
409
		@@:
410
		cmp edx,0
411
		je .24no_crop_bottom
412
			cmp edx,buf2d_h
413
			jge .24no_crop_bottom ;что-бы не получить пустой буфер
414
			sub buf2d_h,edx ;уменьшаем высоту буфера
415
			mov ecx,buf2d_h
416
			imul ecx,ebx ;ecx = новый размер изображения
417
			invoke mem.realloc,buf2d_data,ecx
418
			mov buf2d_data,eax ;на случай если изменился указатель на данные
419
	.24no_crop_bottom:
420
 
421
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
422
	jae .24no_crop_top
423
		mov eax,dword[color]
424
		mov edx,eax ;ax = colors - r,g
425
		shr edx,16 ;dl = color - b
426
		mov esi,buf2d_data
427
		mov ecx,buf2d_h
1555 IgorA 428
		cmp ecx,1
429
		jle .24no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 430
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
431
		mov ebx,buf2d_w
432
		imul ecx,ebx
433
		cld
434
		@@:
435
			cmp word[esi],ax
436
			jne @f
437
			cmp byte[esi+2],dl
438
			jne @f
439
			add esi,3
440
			loop @b
441
		@@:
442
		lea ebx,[ebx+ebx*2]
443
		xor edx,edx
444
		@@:
445
			sub esi,ebx
446
			cmp esi,buf2d_data
447
			jl @f
448
			inc edx ;вычисляем число полных строк для обрезания
449
			loop @b
450
		@@:
451
		cmp edx,0
452
		je .24no_crop_top
453
			xor eax,eax
454
			sub eax,edx
455
			mov ebx,buf2d_h
456
			sub ebx,edx
457
			stdcall buf_offset_h, edi, eax, edx, ebx ;сдвигаем изображение в буфере вверх (eax<0)
458
			sub buf2d_h,edx ;уменьшаем высоту буфера
459
			mov ecx,buf2d_h
460
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
461
			mov ebx,buf2d_w
462
			imul ecx,ebx
463
			lea ecx,[ecx+ecx*2]
464
			invoke mem.realloc,buf2d_data,ecx
465
			mov buf2d_data,eax ;на случай если изменился указатель на данные
466
	.24no_crop_top:
467
 
468
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
469
	jae .24no_crop_right
470
		mov eax,dword[color]
471
		mov edx,eax ;ax = colors - r,g
472
		shr edx,16 ;dl = color - b
473
		mov ebx,buf2d_w
1555 IgorA 474
		cmp ebx,1
475
		jle .24no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 476
		lea ebx,[ebx+ebx*2]
477
		mov esi,ebx
478
		imul esi,buf2d_h
479
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
480
		mov dword[crop_r],0
481
		cld
1538 IgorA 482
		.24found_beg_right:
1535 IgorA 483
		sub esi,3 ;двигаемся на 1-ну колонку влево
484
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
485
		@@:
486
			cmp word[esi],ax
1538 IgorA 487
			jne .24found_right
1535 IgorA 488
			cmp byte[esi+2],dl
1538 IgorA 489
			jne .24found_right
1535 IgorA 490
			sub esi,ebx ;прыгаем на верхнюю строку
491
			loop @b
492
		inc dword[crop_r]
493
 
494
		mov ecx,buf2d_w
495
		dec ecx ;1 колонка на запас
496
		cmp dword[crop_r],ecx
1538 IgorA 497
		jge .24found_right
1535 IgorA 498
 
499
		sub esi,3 ;двигаемся на 1-ну колонку влево
500
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
501
		@@:
502
			add esi,ebx ;прыгаем на нижнюю строку
503
			cmp word[esi],ax
1538 IgorA 504
			jne .24found_right
1535 IgorA 505
			cmp byte[esi+2],dl
1538 IgorA 506
			jne .24found_right
1535 IgorA 507
			loop @b
508
		inc dword[crop_r]
509
 
510
		mov ecx,buf2d_w
511
		dec ecx ;1 колонка на запас
512
		cmp dword[crop_r],ecx
1538 IgorA 513
		jl .24found_beg_right
1535 IgorA 514
 
1538 IgorA 515
		.24found_right:
1535 IgorA 516
		cmp dword[crop_r],0
517
		je .24no_crop_right
518
			mov ecx,buf2d_w
519
			sub ecx,dword[crop_r]
1538 IgorA 520
			stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 521
			mov buf2d_w,ecx ;ставим новую ширину для буфера
522
			mov ebx,buf2d_h
523
			imul ecx,ebx
524
			lea ecx,[ecx+ecx*2]
525
			invoke mem.realloc,buf2d_data,ecx
526
			mov buf2d_data,eax ;на случай если изменился указатель на данные
527
	.24no_crop_right:
528
 
1538 IgorA 529
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
530
	jae .24no_crop_left
531
		mov eax,dword[color]
532
		mov edx,eax ;ax = colors - r,g
533
		shr edx,16 ;dl = color - b
534
		mov ebx,buf2d_w
1555 IgorA 535
		cmp ebx,1
536
		jle .24no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 537
		lea ebx,[ebx+ebx*2]
538
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
539
		mov dword[crop_r],0
540
		cld
541
		.24found_beg_left:
542
 
543
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
544
		@@:
545
			cmp word[esi],ax
546
			jne .24found_left
547
			cmp byte[esi+2],dl
548
			jne .24found_left
549
			add esi,ebx ;прыгаем на нижнюю строку
550
			loop @b
551
		inc dword[crop_r]
552
		add esi,3 ;двигаемся на 1-ну колонку вправо
553
 
554
		mov ecx,buf2d_w
555
		dec ecx ;1 колонка на запас
556
		cmp dword[crop_r],ecx
557
		jge .24found_left
558
 
559
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
560
		@@:
561
			sub esi,ebx ;прыгаем на верхнюю строку
562
			cmp word[esi],ax
563
			jne .24found_left
564
			cmp byte[esi+2],dl
565
			jne .24found_left
566
			loop @b
567
		inc dword[crop_r]
568
		add esi,3 ;двигаемся на 1-ну колонку вправо
569
 
570
		mov ecx,buf2d_w
571
		dec ecx ;1 колонка на запас
572
		cmp dword[crop_r],ecx
573
		jl .24found_beg_left
574
 
575
		.24found_left:
576
		cmp dword[crop_r],0
577
		je .24no_crop_left
578
			mov ecx,buf2d_w
579
			sub ecx,dword[crop_r]
580
			stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
581
			mov buf2d_w,ecx ;ставим новую ширину для буфера
582
			mov ebx,buf2d_h
583
			imul ecx,ebx
584
			lea ecx,[ecx+ecx*2]
585
			invoke mem.realloc,buf2d_data,ecx
586
			mov buf2d_data,eax ;на случай если изменился указатель на данные
587
			mov eax,dword[crop_r]
588
			add buf2d_l,ax
589
	.24no_crop_left:
590
 
1535 IgorA 591
	.24end_f:
592
 
593
 
594
	cmp buf2d_bits,8
595
	jne .8end_f
596
 
597
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
598
	jae .8no_crop_bottom
599
		mov eax,dword[color]
600
		mov esi,buf2d_data
601
		mov ecx,buf2d_h
1555 IgorA 602
		cmp ecx,1
603
		jle .8no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 604
		mov ebx,buf2d_w
605
		imul ecx,ebx
606
		mov esi,ecx
607
		add esi,buf2d_data
608
		cld
609
		@@:
610
			dec esi
611
			cmp byte[esi],al
612
			jne @f
613
			loop @b
614
		@@:
615
		xor edx,edx
616
		mov eax,buf2d_h
617
		imul eax,ebx
618
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
619
		@@:
620
			add esi,ebx
621
			cmp esi,eax
622
			jge @f
623
			inc edx
624
			loop @b
625
		@@:
626
		cmp edx,0
627
		je .8no_crop_bottom
628
			cmp edx,buf2d_h
629
			jge .8no_crop_bottom ;что-бы не получить пустой буфер
630
			sub buf2d_h,edx ;уменьшаем высоту буфера
631
			mov ecx,buf2d_h
632
			imul ecx,ebx ;ecx = новый размер изображения
633
			invoke mem.realloc,buf2d_data,ecx
634
			mov buf2d_data,eax ;на случай если изменился указатель на данные
635
	.8no_crop_bottom:
636
 
637
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
638
	jae .8no_crop_top
639
		mov eax,dword[color]
640
		mov esi,buf2d_data
641
		mov ecx,buf2d_h
1555 IgorA 642
		cmp ecx,1
643
		jle .8no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 644
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
645
		mov ebx,buf2d_w
646
		imul ecx,ebx
647
		cld
648
		@@:
649
			cmp byte[esi],al
650
			jne @f
651
			inc esi
652
			loop @b
653
		@@:
654
		xor edx,edx
655
		@@:
656
			sub esi,ebx
657
			cmp esi,buf2d_data
658
			jl @f
659
			inc edx
660
			loop @b
661
		@@:
662
		cmp edx,0
663
		je .8no_crop_top
664
			xor eax,eax
665
			sub eax,edx
666
			mov ebx,buf2d_h
667
			sub ebx,edx
668
			stdcall buf_offset_h, edi, eax, edx, ebx
669
			mov ecx,buf2d_h
670
			sub ecx,edx
671
			mov buf2d_h,ecx ;уменьшаем высоту буфера
672
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
673
			mov ebx,buf2d_w
674
			imul ecx,ebx
675
			invoke mem.realloc,buf2d_data,ecx
676
			mov buf2d_data,eax ;на случай если изменился указатель на данные
677
	.8no_crop_top:
678
 
679
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
680
	jae .8no_crop_right
681
		mov eax,dword[color]
682
		mov ebx,buf2d_w
1555 IgorA 683
		cmp ebx,1
684
		jle .8no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 685
		mov esi,ebx
686
		imul esi,buf2d_h
687
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
688
		xor edx,edx
689
		cld
690
 
691
		.8found_beg:
692
		dec esi ;двигаемся на 1-ну колонку влево
693
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
694
		@@:
695
			cmp byte[esi],al
696
			jne .8found
697
			sub esi,ebx ;прыгаем на верхнюю строку
698
			loop @b
699
		inc edx
700
		mov ecx,buf2d_w
701
		dec ecx ;1 колонка на запас
702
		cmp edx,ecx
703
		jge .8found
704
 
705
		dec esi ;двигаемся на 1-ну колонку влево
706
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
707
		@@:
708
			add esi,ebx ;прыгаем на нижнюю строку
709
			cmp byte[esi],al
710
			jne .8found
711
			loop @b
712
		inc edx
713
 
714
		mov ecx,buf2d_w
715
		dec ecx ;1 колонка на запас
716
		cmp edx,ecx
717
		jl .8found_beg
718
 
719
		.8found:
720
		cmp edx,0
721
		je .8no_crop_right
722
			mov ecx,buf2d_w
723
			sub ecx,edx
1538 IgorA 724
			stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 725
			mov buf2d_w,ecx ;ставим новую ширину для буфера
726
			mov ebx,buf2d_h
727
			imul ecx,ebx
728
			invoke mem.realloc,buf2d_data,ecx
729
			mov buf2d_data,eax ;на случай если изменился указатель на данные
730
	.8no_crop_right:
731
 
1538 IgorA 732
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
733
	jae .8no_crop_left
734
		mov eax,dword[color]
735
		mov ebx,buf2d_w
1555 IgorA 736
		cmp ebx,1
737
		jle .8no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 738
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
739
		mov edx,0
740
		cld
741
		.8found_beg_left:
742
 
743
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
744
		@@:
745
			cmp word[esi],ax
746
			jne .8found_left
747
			add esi,ebx ;прыгаем на нижнюю строку
748
			loop @b
749
		inc edx
750
		inc esi ;двигаемся на 1-ну колонку вправо
751
 
752
		mov ecx,buf2d_w
753
		dec ecx ;1 колонка на запас
754
		cmp edx,ecx
755
		jge .8found_left
756
 
757
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
758
		@@:
759
			sub esi,ebx ;прыгаем на верхнюю строку
760
			cmp word[esi],ax
761
			jne .8found_left
762
			loop @b
763
		inc edx
764
		inc esi ;двигаемся на 1-ну колонку вправо
765
 
766
		mov ecx,buf2d_w
767
		dec ecx ;1 колонка на запас
768
		cmp edx,ecx
769
		jl .8found_beg_left
770
 
771
		.8found_left:
772
		cmp edx,0
773
		je .8no_crop_left
774
			mov ecx,buf2d_w
775
			sub ecx,edx
776
			stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
777
			mov buf2d_w,ecx ;ставим новую ширину для буфера
778
			mov ebx,buf2d_h
779
			imul ecx,ebx
780
			invoke mem.realloc,buf2d_data,ecx
781
			mov buf2d_data,eax ;на случай если изменился указатель на данные
782
			mov eax,edx
783
			add buf2d_l,ax
784
	.8no_crop_left:
785
 
1535 IgorA 786
	.8end_f:
787
 
788
	popad
789
	ret
790
endp
791
 
1538 IgorA 792
;обрезаем цветное изображение с правой стороны
1535 IgorA 793
;input:
794
;data_rgb - pointer to rgb data
795
;size_w_old - width img in pixels
796
;size_w_new - new width img in pixels
797
;size_h - height img in pixels
798
align 4
1538 IgorA 799
proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 800
	pushad
801
	mov eax, dword[size_w_old]
802
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
803
	mov ebx, dword[size_w_new]
804
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
805
	mov edx, dword[size_h]
806
	mov edi, dword[data_rgb] ;edi - получает данные
807
	mov esi, edi
808
	add edi, ebx
809
	add esi, eax
810
	cld
811
	@@:
812
		dec edx ;уменьшаем счетчик оставшихся строк на 1
813
		cmp edx,0
814
		jle @f
815
		mov ecx, ebx
816
		rep movsb ;перенос (копирование) строки пикселей
817
		add esi,eax ;переход на новую строчку изображения
818
		sub esi,ebx
819
		jmp @b
820
	@@:
821
	popad
822
	ret
823
endp
824
 
1538 IgorA 825
;обрезаем серое изображение с правой стороны
1535 IgorA 826
;input:
827
;data_gray - pointer to gray data
828
;size_w_old - width img in pixels
829
;size_w_new - new width img in pixels
830
;size_h - height img in pixels
831
align 4
1538 IgorA 832
proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 833
	pushad
834
	mov eax, dword[size_w_old]
835
	mov ebx, dword[size_w_new]
836
	mov edx, dword[size_h]
837
	mov edi, dword[data_gray] ;edi - получает данные
838
	mov esi, edi
839
	add edi, ebx
840
	add esi, eax
841
	cld
842
	@@:
843
		dec edx ;уменьшаем счетчик оставшихся строк на 1
844
		cmp edx,0
845
		jle @f
846
		mov ecx, ebx
847
		rep movsb ;перенос (копирование) строки пикселей
848
		add esi,eax ;переход на новую строчку изображения
849
		sub esi,ebx
850
		jmp @b
851
	@@:
852
	popad
853
	ret
854
endp
855
 
1538 IgorA 856
;обрезаем цветное изображение с левой стороны
857
;input:
858
;data_rgb - pointer to rgb data
859
;size_w_old - width img in pixels
860
;size_w_new - new width img in pixels
861
;size_h - height img in pixels
862
align 4
863
proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
864
	pushad
865
	mov edi,dword[data_rgb]
866
	mov esi,edi
867
	mov eax,dword[size_w_old]
868
	mov ebx,dword[size_w_new]
869
	cmp eax,ebx
870
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
871
		lea eax,[eax+eax*2]
872
		lea ebx,[ebx+ebx*2]
873
		sub eax,ebx
874
		mov edx,dword[size_h] ;высота изображения
875
		cld
876
		@@:
877
			add esi,eax
878
			mov ecx,ebx
879
			rep movsb
880
			dec edx
881
			cmp edx,0
882
			jg @b
883
	.end_f:
884
	popad
885
	ret
886
endp
887
 
888
;обрезаем серое изображение с левой стороны
889
;input:
890
;data_gray - pointer to gray data
891
;size_w_old - width img in pixels
892
;size_w_new - new width img in pixels
893
;size_h - height img in pixels
894
align 4
895
proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
896
	pushad
897
	mov edi,dword[data_gray]
898
	mov esi,edi
899
	mov eax,dword[size_w_old]
900
	mov ebx,dword[size_w_new]
901
	cmp eax,ebx
902
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
903
		sub eax,ebx
904
		mov edx,dword[size_h] ;высота изображения
905
		cld
906
		@@:
907
			add esi,eax
908
			mov ecx,ebx
909
			rep movsb
910
			dec edx
911
			cmp edx,0
912
			jg @b
913
	.end_f:
914
	popad
915
	ret
916
endp
917
 
1535 IgorA 918
;hoffs - колличество пикселей на котрые поднимается/опускается изображение
919
;img_t - высота, с которой начинается двигающаяся часть изображения
920
align 4
921
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;сдвигает изображение по высоте
922
	pushad
923
	mov edi,dword[buf_struc]
924
	cmp buf2d_bits,24
925
	jne .end_move_24
926
 
927
	mov eax,[hoffs]
928
	cmp eax,0
929
	je .end_move_24
930
		mov ebx,buf2d_w
931
		mov edx,dword[img_t]
932
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
933
			cmp ecx,buf2d_h
934
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
935
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
936
			lea ecx,[ecx+ecx*2]
937
		imul ebx,edx
938
		lea ebx,[ebx+ebx*2]
939
		mov esi,buf2d_data
940
		add esi,ebx
941
 
942
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
943
		mov ebx,buf2d_w
944
		imul ebx,edx
945
		lea ebx,[ebx+ebx*2]
946
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
947
		add edi,ebx
948
 
949
		cmp eax,0
950
		jg .move_down_24
951
			;двигаем изображение вверх
952
			cld
953
			rep movsb
954
			jmp .end_f
955
		.move_down_24:
956
			;двигаем изображение вниз
957
			add esi,ecx
958
			dec esi
959
			add edi,ecx
960
			dec edi
961
			std
962
			rep movsb
963
			jmp .end_f
964
	.end_move_24:
965
 
966
;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b
967
 
968
	cmp buf2d_bits,8
969
	jne .end_move_8
970
 
971
	mov eax,[hoffs]
972
	cmp eax,0
973
	je .end_move_8
974
		;двигаем изображение вверх
975
		mov ebx,buf2d_w
976
		mov edx,dword[img_t]
977
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
978
			cmp ecx,buf2d_h
979
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
980
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
981
		imul ebx,edx
982
		mov esi,buf2d_data
983
		add esi,ebx
984
 
985
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
986
		mov ebx,buf2d_w
987
		imul ebx,edx
988
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
989
		add edi,ebx
990
 
991
		cmp eax,0
992
		jg .move_down_8
993
			cld
994
			rep movsb
995
			jmp .end_f
996
		.move_down_8:
997
			;двигаем изображение вниз
998
			add esi,ecx
999
			dec esi
1000
			add edi,ecx
1001
			dec edi
1002
			std
1003
			rep movsb
1004
			jmp .end_f
1005
	.end_move_8:
1006
 
1007
	.end_f:
1008
	popad
1009
	ret
1010
endp
1011
 
1012
 
1013
align 4
1014
proc buf_draw_buf, buf_struc:dword
1015
	pushad
1016
	mov edi,dword[buf_struc]
1017
	cmp buf2d_bits,24
1018
	jne .error
1019
		mov eax,7
1020
		mov ebx,buf2d_data
1021
 
1022
		mov ecx,buf2d_w
1023
		ror ecx,16
1024
		mov edx,buf2d_h
1025
		mov cx,dx
1026
 
1027
		mov edx,buf2d_size_lt
1028
		ror edx,16
1029
		int 0x40
1030
		jmp .end_draw_24
1031
	.error:
1032
		stdcall print_err,sz_buf2d_draw,txt_err_n24b
1033
	.end_draw_24:
1034
	popad
1035
	ret
1036
endp
1037
 
1038
align 4
1039
proc buf_delete, buf_struc:dword
2136 IgorA 1040
	push eax edi
1535 IgorA 1041
	mov edi,dword[buf_struc]
1042
	invoke mem.free,buf2d_data
2136 IgorA 1043
	pop edi eax
1535 IgorA 1044
	ret
1045
endp
1046
 
1047
align 4
2136 IgorA 1048
proc buf_resize, buf_struc:dword, new_w:dword, new_h:dword
1049
	pushad
1050
	mov edi,dword[buf_struc]
1051
	cmp buf2d_bits,24
1052
	jne .24bit
1053
		mov eax,dword[new_w]
1054
		cmp eax,1
1055
		jl @f
1056
			mov buf2d_w,eax
1057
		@@:
1058
		mov ecx,buf2d_w
1059
		mov eax,dword[new_h]
1060
		cmp eax,1
1061
		jl @f
1062
			mov buf2d_h,eax
1063
		@@:
1064
		mov ebx,buf2d_h
1065
		imul ecx,ebx
1066
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
1067
		invoke mem.realloc,buf2d_data,ecx ;изменяем память занимаемую буфером
1068
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1069
	.24bit:
1070
	popad
1071
	ret
1072
endp
1073
 
1074
align 4
2975 IgorA 1075
rot_table: ;таблица для указания на подфункции для поворотов
1076
	dd buf_rotate.8b90,buf_rotate.24b90,buf_rotate.32b90,\
1077
	buf_rotate.8b180,buf_rotate.24b180,buf_rotate.32b180
1078
 
1079
;поворот изображения на 90 или 180 градусов
1080
align 4
1081
proc buf_rotate, buf_struc:dword, angle:dword
1082
locals
1083
	n_data dd ?
1084
	dec_h dd ? ;число байт, для уменьшения координаты y
1085
endl
1086
	pushad
1087
	mov edi,[buf_struc]
1088
	mov ebx,buf2d_w
1089
	mov ecx,buf2d_h
1090
 
1091
	lea eax,[rot_table]
1092
	cmp dword[angle],90 ;проверка угла поворота
1093
	je .beg_0
1094
	cmp dword[angle],180
1095
	jne @f
1096
		add eax,12
1097
		jmp .beg_0
1098
	@@:
1099
	jmp .end_f
1100
	.beg_0: ;проверка битности буфера
1101
	cmp buf2d_bits,8
1102
	jne @f
1103
		jmp dword[eax]
1104
	@@:
1105
	cmp buf2d_bits,24
1106
	jne @f
1107
		add eax,4
1108
		jmp dword[eax]
1109
	@@:
1110
	cmp buf2d_bits,32
1111
	jne @f
1112
		add eax,8
1113
		jmp dword[eax]
1114
	@@:
1115
	jmp .end_f
1116
 
1117
	.8b90: ;поворот 8 битного буфера на 90 градусов
1118
		mov edx,ecx ;edx - buf_h
1119
		imul ecx,ebx
1120
		invoke mem.alloc,ecx ;выделяем временную память
1121
		cmp eax,0
1122
		je .end_f
1123
		mov [n_data],eax
1124
		mov [dec_h],ecx
1125
		inc dword[dec_h]
1126
 
1127
		;copy buf --> mem
1128
		mov edi,[buf_struc]
1129
		mov esi,buf2d_data
1130
		mov edi,eax ;[n_data]
1131
		dec edx ;коректируем edx на 1 байт, для компенсации сдвига в movsb
1132
		add edi,edx
1133
		xor eax,eax
1134
		cld
1135
		.cycle_0:
1136
			movsb
1137
			add edi,edx
1138
			inc eax
1139
			cmp eax,ebx
1140
			jl @f
1141
				xor eax,eax
1142
				sub edi,[dec_h]
1143
			@@:
1144
			loop .cycle_0
1145
 
1146
		;change buf_w <---> buf_h
1147
		mov esi,[n_data]
1148
		mov edi,[buf_struc]
1149
		mov edi,buf2d_data
1150
		mov ecx,ebx
1151
		inc edx ;исправляем скоректированный edx
1152
		imul ecx,edx
1153
		;copy buf <-- mem
1154
		;cld
1155
		rep movsb
1156
		invoke mem.free,[n_data]
1157
		jmp .change_w_h
1158
	.24b90: ;поворот 24 битного буфера на 90 градусов
1159
		mov esi,ecx
1160
		imul esi,ebx
1161
		lea ecx,[ecx+ecx*2]
1162
		mov edx,ecx ;edx - buf_h * 3
1163
		imul ecx,ebx
1164
		invoke mem.alloc,ecx ;выделяем временную память
1165
		cmp eax,0
1166
		je .end_f
1167
		mov [n_data],eax
1168
		mov [dec_h],ecx
1169
		add dword[dec_h],3
1170
 
1171
		;copy buf --> mem
1172
 
1173
		mov edi,[buf_struc]
1174
		mov ecx,esi
1175
		mov esi,buf2d_data
1176
		mov edi,eax ;[n_data]
1177
		sub edx,3 ;коректируем edx на 3 байта, для компенсации сдвига
1178
		add edi,edx
1179
		xor eax,eax
1180
		cld
1181
		.cycle_1:
1182
			movsw
1183
			movsb
1184
			add edi,edx
1185
			inc eax
1186
			cmp eax,ebx
1187
			jl @f
1188
				xor eax,eax
1189
				sub edi,[dec_h]
1190
			@@:
1191
			loop .cycle_1
1192
 
1193
		;copy buf <-- mem
1194
		mov esi,[n_data]
1195
		mov edi,[buf_struc]
1196
		mov edi,buf2d_data
1197
		mov ecx,ebx
1198
		add edx,3 ;исправляем скоректированный edx
1199
		imul ecx,edx
1200
		;cld
1201
		rep movsb
1202
		invoke mem.free,[n_data]
1203
		jmp .change_w_h
1204
	.32b90: ;поворот 32 битного буфера на 90 градусов
1205
		shl ecx,2
1206
		mov edx,ecx ;edx - buf_h * 4
1207
		imul ecx,ebx
1208
		invoke mem.alloc,ecx ;выделяем временную память
1209
		cmp eax,0
1210
		je .end_f
1211
		mov [n_data],eax
1212
		mov [dec_h],ecx
1213
		add dword[dec_h],4
1214
 
1215
		;copy buf --> mem
1216
		mov edi,[buf_struc]
1217
		shr ecx,2
1218
		mov esi,buf2d_data
1219
		mov edi,eax ;[n_data]
1220
		sub edx,4 ;коректируем edx на 4 байта, для компенсации сдвига в movsd
1221
		add edi,edx
1222
		xor eax,eax
1223
		cld
1224
		.cycle_2:
1225
			movsd
1226
			add edi,edx
1227
			inc eax
1228
			cmp eax,ebx
1229
			jl @f
1230
				xor eax,eax
1231
				sub edi,[dec_h]
1232
			@@:
1233
			loop .cycle_2
1234
 
1235
		;copy buf <-- mem
1236
		mov esi,[n_data]
1237
		mov edi,[buf_struc]
1238
		mov edi,buf2d_data
1239
		mov ecx,ebx
1240
		add edx,4 ;исправляем скоректированный edx
1241
		imul ecx,edx
1242
		shr ecx,2
1243
		;cld
1244
		rep movsd
1245
		invoke mem.free,[n_data]
1246
		;jmp .change_w_h
1247
	.change_w_h: ;change buf_w <---> buf_h
1248
		mov edi,[buf_struc]
1249
		mov eax,buf2d_w
1250
		mov ebx,buf2d_h
1251
		mov buf2d_h,eax
1252
		mov buf2d_w,ebx
1253
		jmp .end_f
1254
	.8b180: ;поворот 8 битного буфера на 180 градусов
1255
		mov edi,buf2d_data
1256
		mov esi,edi
1257
		imul ecx,ebx
1258
		add esi,ecx
1259
		dec esi
1260
		shr ecx,1 ;ecx - число пикселей буфера : 2
1261
		std
1262
		@@:
1263
			lodsb
1264
			mov ah,byte[edi]
1265
			mov byte[esi+1],ah
1266
			mov byte[edi],al
1267
			inc edi
1268
			loop @b
1269
			jmp .end_f
1270
	.24b180: ;поворот 24 битного буфера на 180 градусов
1271
		mov esi,buf2d_data
1272
		mov edi,esi
1273
		imul ecx,ebx
1274
		mov eax,ecx
1275
		lea ecx,[ecx+ecx*2]
1276
		add edi,ecx
1277
		sub edi,3
1278
		shr eax,1
1279
		mov ecx,eax ;ecx - число пикселей буфера : 2
1280
		cld
1281
		@@:
1282
			lodsw
1283
			mov edx,eax
1284
			lodsb
1285
			mov bx,word[edi]
1286
			mov word[esi-3],bx
1287
			mov bl,byte[edi+2]
1288
			mov byte[esi-1],bl
1289
			mov byte[edi+2],al
1290
			mov word[edi],dx
1291
			sub edi,3
1292
			loop @b
1293
			jmp .end_f
1294
	.32b180: ;поворот 32 битного буфера на 180 градусов
1295
		mov edi,buf2d_data
1296
		mov esi,edi
1297
		imul ecx,ebx
1298
		shl ecx,2
1299
		add esi,ecx
1300
		sub esi,4
1301
		shr ecx,3 ;ecx - число пикселей буфера : 2
1302
		std
1303
		@@:
1304
			lodsd
1305
			mov ebx,dword[edi]
1306
			mov dword[esi+4],ebx
1307
			mov dword[edi],eax
1308
			add edi,4
1309
			loop @b
1310
		;jmp .end_f
1311
 
1312
	.end_f:
1313
	popad
1314
	ret
1315
endp
1316
 
1317
align 4
1535 IgorA 1318
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1319
locals
1320
	loc_1 dd ?
1321
	loc_2 dd ?
1322
	napravl db ?
1323
endl
1324
	pushad
1325
		mov eax,dword[coord_x1]
1326
		sub eax,dword[coord_x0]
1327
		bt eax,31
1328
		jae @f
1329
			neg eax
1330
			inc eax
1331
		@@:
1332
		mov ebx,dword[coord_y1]
1333
		sub ebx,dword[coord_y0]
2230 IgorA 1334
		jnz @f
1335
			;если задана горизонтальная линия y0=y1
1336
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1337
			jmp .coord_end
1338
		@@:
1535 IgorA 1339
		bt ebx,31
1340
		jae @f
1341
			neg ebx
1342
			inc ebx
1343
		@@:
2230 IgorA 1344
		mov edx,dword[color]
1535 IgorA 1345
 
1346
		mov [napravl],byte 0 ;bool steep=false
1347
		cmp eax,ebx
1348
		jle @f
1349
			mov [napravl],byte 1 ;bool steep=true
1350
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1351
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1352
		@@:
1353
		mov eax,dword[coord_y0] ;x0
1354
		cmp eax,dword[coord_y1] ;if(x0>x1)
1355
		jle @f
1356
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1357
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1358
		@@:
1359
 
1360
; int deltax esi
1361
; int deltay edi
1362
; int error  ebp-6
1363
; int ystep  ebp-8
1364
 
1365
		mov eax,dword[coord_y0]
1366
		mov esi,dword[coord_y1]
1367
		sub esi,eax ;deltax = y1-y0
1368
		mov ebx,esi
1369
		shr ebx,1
1370
		mov [loc_1],ebx ;error = deltax/2
1371
 
1372
		mov eax,dword[coord_x0]
1373
		mov edi,dword[coord_x1]
1374
		mov [loc_2],dword -1 ;ystep = -1
1375
		cmp eax,edi ;if (x0
1376
		jge @f
1377
			mov [loc_2],dword 1 ;ystep = 1
1378
		@@:
1379
		sub edi,eax ;x1-x0
1380
 
1381
		bts edi,31
1382
		jae @f
1383
			neg edi
1384
			inc edi
1385
		@@:
1386
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1387
 
1388
		mov eax,edi
1389
		mov edi,[buf_struc]
2358 IgorA 1390
		cmp buf2d_bits,8
1391
		je @f
1535 IgorA 1392
		cmp buf2d_bits,24
2358 IgorA 1393
		je @f
1394
			jmp .coord_end
1395
		@@:
1535 IgorA 1396
 
1397
		cmp [napravl],0
1398
		jne .coord_yx
1399
			mov ebx,dword[coord_x0]
1400
			mov ecx,dword[coord_y0]
1401
 
1402
			@@: ;for (x=x0 ; x
1403
				cmp ecx,dword[coord_y1]
1404
				jg @f ;jge ???
1405
				call draw_pixel
1406
 
1407
				sub dword[loc_1],eax ;error -= deltay
1408
				cmp dword[loc_1],0 ;if(error<0)
1409
				jge .if0
1410
					add ebx,[loc_2] ;y += ystep
1411
					add [loc_1],esi ;error += deltax
1412
				.if0:
1413
				inc ecx
1414
				jmp @b
1415
			@@:
1416
			jmp .coord_end
1417
		.coord_yx:
1418
			mov ebx,dword[coord_y0]
1419
			mov ecx,dword[coord_x0]
1420
 
1421
			@@: ;for (x=x0 ; x
1422
				cmp ebx,dword[coord_y1]
1423
				jg @f ;jge ???
1424
				call draw_pixel
1425
 
1426
				sub dword[loc_1],eax ;error -= deltay
1427
				cmp dword[loc_1],0 ;if(error<0)
1428
				jge .if1
1429
					add ecx,[loc_2] ;y += ystep
1430
					add [loc_1],esi ;error += deltax
1431
				.if1:
1432
				inc ebx
1433
				jmp @b
1434
			@@:
1435
	.coord_end:
1436
	popad
1437
	ret
1438
endp
1439
 
2230 IgorA 1440
;рисование сглаженной линии
1441
align 4
1442
proc buf_line_brs_sm, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1443
locals
1444
	loc_1 dd ?
1445
	loc_2 dd ?
1446
	napravl db ?
1447
endl
1448
	pushad
1449
		mov eax,dword[coord_x1]
1450
		sub eax,dword[coord_x0]
1451
		bt eax,31
1452
		jae @f
1453
			neg eax
1454
			inc eax
1455
		@@:
1456
		mov ebx,dword[coord_y1]
1457
		sub ebx,dword[coord_y0]
1458
		jnz @f
1459
			;если задана горизонтальная линия y0=y1
1460
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1461
			jmp .coord_end
1462
		@@:
1463
		bt ebx,31
1464
		jae @f
1465
			neg ebx
1466
			inc ebx
1467
		@@:
1468
		mov edx,dword[color]
1469
 
1470
		mov [napravl],byte 0 ;bool steep=false
1471
		cmp eax,ebx
1472
		jle @f
1473
			mov [napravl],byte 1 ;bool steep=true
1474
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1475
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1476
		@@:
1477
		mov eax,dword[coord_y0] ;x0
1478
		cmp eax,dword[coord_y1] ;if(x0>x1)
1479
		jle @f
1480
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1481
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1482
		@@:
1483
 
1484
; int deltax esi
1485
; int deltay edi
1486
; int error  ebp-6
1487
; int ystep  ebp-8
1488
 
1489
		mov eax,dword[coord_y0]
1490
		mov esi,dword[coord_y1]
1491
		sub esi,eax ;deltax = y1-y0
1492
		mov ebx,esi
1493
		shr ebx,1
1494
		mov [loc_1],ebx ;error = deltax/2
1495
 
1496
		mov eax,dword[coord_x0]
1497
		mov edi,dword[coord_x1]
1498
		mov [loc_2],dword -1 ;ystep = -1
1499
		cmp eax,edi ;if (x0
1500
		jge @f
1501
			mov [loc_2],dword 1 ;ystep = 1
1502
		@@:
1503
		sub edi,eax ;x1-x0
1504
 
1505
		bts edi,31
1506
		jae @f
1507
			neg edi
1508
			inc edi
1509
		@@:
1510
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1511
 
1512
		mov eax,edi
1513
		mov edi,[buf_struc]
1514
		cmp buf2d_bits,24
1515
		jne .coord_end
1516
 
1517
		cmp [napravl],0
1518
		jne .coord_yx
1519
			mov ebx,dword[coord_x0]
1520
			mov ecx,dword[coord_y0]
1521
 
1522
			@@: ;for (x=x0 ; x
1523
				cmp ecx,dword[coord_y1]
1524
				jg @f ;jge ???
1525
				push eax
1526
					mov eax,esi
1527
					sub eax,[loc_1]
1528
					stdcall draw_pixel_transp, eax,esi
1529
				pop eax
1530
				add ebx,[loc_2]
1531
				stdcall draw_pixel_transp, [loc_1],esi
1532
				sub ebx,[loc_2]
1533
 
1534
				sub dword[loc_1],eax ;error -= deltay
1535
				cmp dword[loc_1],0 ;if(error<0)
1536
				jge .if0
1537
					add ebx,[loc_2] ;y += ystep
1538
					add [loc_1],esi ;error += deltax
1539
				.if0:
1540
				inc ecx
1541
				jmp @b
1542
			@@:
1543
			jmp .coord_end
1544
		.coord_yx:
1545
			mov ebx,dword[coord_y0]
1546
			mov ecx,dword[coord_x0]
1547
 
1548
			@@: ;for (x=x0 ; x
1549
				cmp ebx,dword[coord_y1]
1550
				jg @f ;jge ???
1551
				push eax
1552
					mov eax,esi
1553
					sub eax,[loc_1]
1554
					stdcall draw_pixel_transp, eax,esi
1555
				pop eax
1556
				add ecx,[loc_2]
1557
				stdcall draw_pixel_transp, [loc_1],esi
1558
				sub ecx,[loc_2]
1559
 
1560
				sub dword[loc_1],eax ;error -= deltay
1561
				cmp dword[loc_1],0 ;if(error<0)
1562
				jge .if1
1563
					add ecx,[loc_2] ;y += ystep
1564
					add [loc_1],esi ;error += deltax
1565
				.if1:
1566
				inc ebx
1567
				jmp @b
1568
			@@:
1569
	.coord_end:
1570
	popad
1571
	ret
1572
endp
1573
 
1653 IgorA 1574
;рисование горизонтальной линии, потому нет параметра coord_y1
1535 IgorA 1575
align 4
1634 IgorA 1576
proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
1577
	pushad
2358 IgorA 1578
	pushfd
1634 IgorA 1579
		mov edi,[buf_struc]
2358 IgorA 1580
		cmp buf2d_bits,8
1581
		je @f
1634 IgorA 1582
		cmp buf2d_bits,24
2358 IgorA 1583
		je @f
1584
			jmp .end24
1585
		@@: ;определение координат линии относительно буфера
1634 IgorA 1586
 
2177 IgorA 1587
		mov ecx,dword[coord_y0]
1588
		bt ecx,31
1589
		jc .end24 ;если координата y0 отрицательная
1590
		cmp ecx,buf2d_h
1591
		jge .end24 ;если координата y0 больше высоты буфера
1592
 
1634 IgorA 1593
		mov ebx,dword[coord_x0]
1594
		mov esi,dword[coord_x1]
1717 IgorA 1595
		cmp ebx,esi
1596
		jle @f
1597
			xchg ebx,esi ;если x0 > x1 то меняем местами x0 и x1
2177 IgorA 1598
		@@:
2185 IgorA 1599
		bt ebx,31
1600
		jae @f
1601
			;если координата x0 отрицательная
1602
			xor ebx,ebx
1603
		@@:
2177 IgorA 1604
		cmp esi,buf2d_w
1605
		jl @f
2185 IgorA 1606
			;если координата x0 больше ширины буфера
2177 IgorA 1607
			mov esi,buf2d_w
2359 IgorA 1608
			dec esi
2177 IgorA 1609
		@@:
2185 IgorA 1610
		cmp ebx,esi
2358 IgorA 1611
		jg .end24 ;если x0 > x1 может возникнуть когда обе координаты x0, x1 находились за одним из пределов буфера
1717 IgorA 1612
 
2358 IgorA 1613
		cmp buf2d_bits,24
1614
		je .beg24
1615
			;рисование в 8 битном буфере
1616
			;в edx вычисляем начало 1-й точки линии в буфере изображения
1617
			mov edx,buf2d_w ;size x
1618
			imul edx,ecx ;size_x*y
1619
			add edx,ebx	 ;size_x*y+x
1620
			add edx,buf2d_data ;ptr+(size_x*y+x)
1621
			mov edi,edx ;теперь можем портить указатель на буфер
1622
 
1623
			mov ecx,esi
1624
			sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
1625
			inc ecx ;что-бы последняя точка линии также отображалась
1626
			mov eax,dword[color] ;будем использовать только значение в al
1627
			cld
1628
			rep stosb ;цикл по оси x от x0 до x1 (включая x1)
1629
			jmp .end24
1630
 
1631
		.beg24: ;рисование в 24 битном буфере
2177 IgorA 1632
		;в eax вычисляем начало 1-й точки линии в буфере изображения
1633
		mov eax,buf2d_w ;size x
1634
		imul eax,ecx ;size_x*y
1635
		add eax,ebx	 ;size_x*y+x
1636
		lea eax,[eax+eax*2] ;(size_x*y+x)*3
1637
		add eax,buf2d_data  ;ptr+(size_x*y+x)*3
1638
 
2185 IgorA 1639
		mov ecx,esi
1640
		sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
2358 IgorA 1641
		inc ecx ;что-бы последняя точка линии также отображалась
2177 IgorA 1642
		mov edx,dword[color]
2185 IgorA 1643
		mov ebx,edx ;координата x0 в ebx уже не нужна
1644
		ror edx,16 ;поворачиваем регистр что бы 3-й байт попал в dl
1645
		cld
2358 IgorA 1646
		@@: ;цикл по оси x от x0 до x1 (включая x1)
2185 IgorA 1647
			mov word[eax],bx ;copy pixel color
1648
			mov byte[eax+2],dl
1649
			add eax,3
1650
			loop @b
1684 IgorA 1651
		.end24:
2358 IgorA 1652
	popfd
1634 IgorA 1653
	popad
1654
	ret
1655
endp
1656
 
1657
align 4
1658
proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1659
pushad
1660
	mov edi,[buf_struc]
2358 IgorA 1661
	cmp buf2d_bits,8
1662
	je @f
1634 IgorA 1663
	cmp buf2d_bits,24
2358 IgorA 1664
	je @f
1665
		jmp .coord_end
1666
	@@:
1634 IgorA 1667
 
1668
		mov eax,[coord_x]
1669
		mov ebx,[coord_y]
1670
		mov ecx,[w]
2358 IgorA 1671
		;cmp ecx,1
1672
		;jl .coord_end
1673
		cmp ecx,0
1674
		je .coord_end
1675
		jg @f
1676
			add eax,ecx
1677
			inc eax
1678
			neg ecx
1679
		@@:
1634 IgorA 1680
		add ecx,eax
1642 IgorA 1681
		dec ecx
1634 IgorA 1682
		mov edx,[h]
2358 IgorA 1683
		;cmp edx,1
1684
		;jl .coord_end
1685
		cmp edx,0
1686
		je .coord_end
1687
		jg @f
1688
			add ebx,edx
1689
			inc ebx
1690
			neg edx
1691
		@@:
1642 IgorA 1692
 
1634 IgorA 1693
		add edx,ebx
1642 IgorA 1694
		dec edx
1634 IgorA 1695
		mov esi,dword[color]
1696
		stdcall buf_line_h, edi, eax, ebx, ecx, esi ;линия -
1697
		stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;линия |
1698
		stdcall buf_line_h, edi, eax, edx, ecx, esi ;линия -
1699
		stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;линия |
1700
	.coord_end:
1701
popad
1702
	ret
1703
endp
1704
 
1705
align 4
1642 IgorA 1706
proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1707
pushad
1708
	mov edi,[buf_struc]
2358 IgorA 1709
	cmp buf2d_bits,8
1710
	je @f
1642 IgorA 1711
	cmp buf2d_bits,24
2358 IgorA 1712
	je @f
1713
		jmp .coord_end
1714
	@@:
1642 IgorA 1715
		mov eax,[coord_x]
1716
		mov ebx,[coord_y]
1717
		mov edx,[w]
2358 IgorA 1718
		cmp edx,0
1719
		je .coord_end ;если высота 0 пикселей
1720
		jg @f ;если высота положительная
1721
			add eax,edx
1722
			inc eax
1723
			neg edx ;ширину делаем положительной
1724
			;inc edx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1725
		@@:
1642 IgorA 1726
		add edx,eax
2358 IgorA 1727
		dec edx
1642 IgorA 1728
		mov ecx,[h]
2358 IgorA 1729
		cmp ecx,0
1730
		je .coord_end ;если высота 0 пикселей
1731
		jg @f ;если высота положительная
1732
			add ebx,ecx ;сдвигаем верхнюю координату прямоугольника
1733
			inc ebx
1734
			neg ecx ;высоту делаем положительной
1735
			;inc ecx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1736
		@@:
1642 IgorA 1737
		mov esi,dword[color]
1738
		cld
1739
		@@:
1740
			stdcall buf_line_h, edi, eax, ebx, edx, esi ;линия -
1741
			inc ebx
1742
			loop @b
1743
	.coord_end:
1744
popad
1745
	ret
1746
endp
1747
 
1748
align 4
1535 IgorA 1749
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
1750
locals
1751
	po_x dd ?
1752
	po_y dd ?
1753
endl
1754
	pushad
1755
	mov edi,dword[buf_struc]
2358 IgorA 1756
	cmp buf2d_bits,8
1757
	je @f
1535 IgorA 1758
	cmp buf2d_bits,24
2358 IgorA 1759
	je @f
1760
		jmp .error
1761
	@@:
1535 IgorA 1762
		mov edx,dword[color]
1763
 
1764
		finit
1765
		fild dword[coord_x]
1766
		fild dword[coord_y]
1767
		fild dword[r]
1768
		fldz ;px=0
1769
		fld st1 ;py=r
1770
 
1771
		fldpi
1772
		fmul st0,st3
1773
		fistp dword[po_x]
1774
		mov esi,dword[po_x] ;esi=pi*r
1775
		shl esi,1 ;esi=2*pi*r
1776
 
1777
		;st0 = py
1778
		;st1 = px
1779
		;st2 = r
1780
		;st3 = y
1781
		;st4 = x
1782
 
1783
		@@:
1784
			;Point(px + x, y - py)
1785
			fld st1 ;st0=px
1786
			fadd st0,st5 ;st0=px+x
1787
			fistp dword[po_x]
1788
			mov ebx,dword[po_x]
1789
			fld st3 ;st0=y
1790
			fsub st0,st1 ;st0=y-py
1791
			fistp dword[po_y]
1792
			mov ecx,dword[po_y]
1793
			call draw_pixel
1794
			;px += py/r
1795
			fld st0 ;st0=py
1796
			fdiv st0,st3 ;st0=py/r
1797
			faddp st2,st0 ;st3+=st0
1798
			;py -= px/r
1799
			fld st1 ;st0=px
1800
			fdiv st0,st3 ;st0=px/r
1801
			fsubp st1,st0 ;st2-=st0
1802
 
1803
			dec esi
1804
			cmp esi,0
1805
			jge @b
1806
		jmp .exit_fun
1807
	.error:
2358 IgorA 1808
		stdcall print_err,sz_buf2d_circle,txt_err_n8_24b
1535 IgorA 1809
	.exit_fun:
1810
 
1811
	popad
1812
	ret
1813
endp
1814
 
1684 IgorA 1815
;функция для заливки области выбранным цветом
1535 IgorA 1816
align 4
1684 IgorA 1817
proc buf_flood_fill, buf_struc:dword, coord_x:dword, coord_y:dword, mode:dword, color_f:dword, color_b:dword
1818
	pushad
1819
		mov edi,[buf_struc]
1820
		cmp buf2d_bits,24
1821
		jne .end24
1822
 
1823
			mov ebx,dword[coord_x]
1824
			mov ecx,dword[coord_y]
1825
			mov edx,dword[color_f]
1826
			mov esi,dword[color_b]
1827
 
1828
			cmp dword[mode],1 ;в зависимости от 'mode' определяем каким алгоритмом будем пользоваться
1829
			je @f
1830
				call buf_flood_fill_recurs_0 ;заливаем до пикселей цвета esi
1831
				jmp .end24
1832
			@@:
1833
				call buf_flood_fill_recurs_1 ;заливаем пиксели имеющие цвет esi
1834
 
1835
		.end24:
1836
	popad
1837
	ret
1838
endp
1839
 
1840
;input:
1841
; ebx = coord_x
1842
; ecx = coord_y
1843
; edx = цвет заливки
1844
; esi = цвет границы, до которой будет ити заливка
1845
; edi = buf_struc
1846
;output:
1847
; eax = портится
1848
align 4
1849
buf_flood_fill_recurs_0:
1850
	call get_pixel_24
1851
	cmp eax,0xffffffff ;if error coords
1852
	je .end_fun
1853
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1854
	je .end_fun
1855
 
1856
		call draw_pixel
1857
 
1858
		dec ebx
1859
		call get_pixel_24
1860
		cmp eax,esi
1861
		je @f
1862
			call buf_flood_fill_recurs_0
1863
		@@:
1864
		inc ebx
1865
 
1866
 
1867
		inc ebx
1868
		call get_pixel_24
1869
		cmp eax,esi
1870
		je @f
1871
			call buf_flood_fill_recurs_0
1872
		@@:
1873
		dec ebx
1874
 
1875
		dec ecx
1876
		call get_pixel_24
1877
		cmp eax,esi
1878
		je @f
1879
			call buf_flood_fill_recurs_0
1880
		@@:
1881
		inc ecx
1882
 
1883
		inc ecx
1884
		call get_pixel_24
1885
		cmp eax,esi
1886
		je @f
1887
			call buf_flood_fill_recurs_0
1888
		@@:
1889
		dec ecx
1890
 
1891
	.end_fun:
1892
	ret
1893
 
1894
;input:
1895
; ebx = coord_x
1896
; ecx = coord_y
1897
; edx = цвет заливки
1898
; esi = цвет пикселей, по которым будет ити заливка
1899
; edi = buf_struc
1900
;output:
1901
; eax = портится
1902
align 4
1903
buf_flood_fill_recurs_1:
1904
	call get_pixel_24
1905
	cmp eax,0xffffffff ;if error coords
1906
	je .end_fun
1907
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1908
	je .end_fun
1909
	cmp eax,esi ;если цвет пикселя не совпал с заливаемым цветом заливки, то прекращаем заливку
1910
	jne .end_fun
1911
 
1912
		call draw_pixel
1913
 
1914
		dec ebx
1915
		call get_pixel_24
1916
		cmp eax,esi
1917
		jne @f
1918
			call buf_flood_fill_recurs_1
1919
		@@:
1920
		inc ebx
1921
 
1922
 
1923
		inc ebx
1924
		call get_pixel_24
1925
		cmp eax,esi
1926
		jne @f
1927
			call buf_flood_fill_recurs_1
1928
		@@:
1929
		dec ebx
1930
 
1931
		dec ecx
1932
		call get_pixel_24
1933
		cmp eax,esi
1934
		jne @f
1935
			call buf_flood_fill_recurs_1
1936
		@@:
1937
		inc ecx
1938
 
1939
		inc ecx
1940
		call get_pixel_24
1941
		cmp eax,esi
1942
		jne @f
1943
			call buf_flood_fill_recurs_1
1944
		@@:
1945
		dec ecx
1946
 
1947
	.end_fun:
1948
	ret
1949
 
1910 IgorA 1950
;функция для рисования точки
1684 IgorA 1951
align 4
2658 IgorA 1952
proc buf_set_pixel uses ebx ecx edx edi, buf_struc:dword, coord_x:dword, coord_y:dword, color:dword
1953
	mov edi,dword[buf_struc]
1954
	mov ebx,dword[coord_x]
1955
	mov ecx,dword[coord_y]
1956
	mov edx,dword[color]
1957
	call draw_pixel
1910 IgorA 1958
	ret
1959
endp
1960
 
2658 IgorA 1961
;output:
1962
; eax = цвет точки
1963
; в случае ошибки eax = 0xffffffff
1910 IgorA 1964
align 4
2658 IgorA 1965
proc buf_get_pixel uses ebx ecx edi, buf_struc:dword, coord_x:dword, coord_y:dword
1966
	mov edi,dword[buf_struc]
1967
	mov ebx,[coord_x]
1968
	mov ecx,[coord_y]
1969
 
1970
	cmp buf2d_bits,8
1971
	jne @f
1972
		call get_pixel_8
1973
		jmp .end_fun
1974
	@@:
1975
	cmp buf2d_bits,24
1976
	jne @f
1977
		call get_pixel_24
1978
		jmp .end_fun
1979
	@@:
1980
	cmp buf2d_bits,32
1981
	jne @f
1982
		call get_pixel_32
1983
		;jmp .end_fun
1984
	@@:
1985
	.end_fun:
1986
	ret
1987
endp
1988
 
3040 IgorA 1989
;отразить по вертикали (верх и низ меняются местами)
2658 IgorA 1990
align 4
3040 IgorA 1991
proc buf_flip_v, buf_struc:dword
1992
locals
1993
    line_pix dd ? ;кол. пикселей в линии буфера
1994
    line_2byte dd ? ;кол. байт в линии буфера * 2
1995
endl
1996
	pushad
1997
	mov edi,[buf_struc]
1998
    cmp buf2d_bits,24
1999
    jne .end_24
2000
        mov edx,buf2d_w
2001
        mov [line_pix],edx
2002
        mov ebx,buf2d_h
2003
        lea edx,[edx+edx*2]
2004
        mov esi,edx
2005
        imul esi,ebx
2006
        sub esi,edx
2007
        add esi,buf2d_data ;указатель на нижнюю линию
2008
        shr ebx,1 ;кол. линейных циклов
2009
        shl edx,1
2010
        mov [line_2byte],edx
2011
        mov edi,buf2d_data
2012
        xchg edi,esi
2013
        cld
2014
        .flip_24:
2015
        cmp ebx,0
2016
        jle .end_24
2017
        mov ecx,[line_pix]
2018
        @@:
2019
            lodsw
2020
            mov dx,word[edi]
2021
            mov word[esi-2],dx
2022
            mov [edi],ax
2023
            lodsb
2024
            mov ah,byte[edi+2]
2025
            mov byte[esi-1],ah
2026
            mov [edi+2],al
2027
            add edi,3
2028
            loop @b
2029
        sub edi,[line_2byte]
2030
        dec ebx
2031
        jmp .flip_24
2032
    .end_24:
2033
    popad
2034
    ret
2035
endp
2036
 
2037
align 4
1535 IgorA 2038
proc buf_img_wdiv2, buf_struc:dword
2039
	pushad
2040
	mov edi,dword[buf_struc]
2927 IgorA 2041
	cmp buf2d_bits,8
2042
	jne @f
2043
		mov eax,buf2d_w
2044
		mov ecx,buf2d_h
2045
		imul ecx,eax
2046
		stdcall img_8b_wdiv2, buf2d_data,ecx
2047
	@@:
1535 IgorA 2048
	cmp buf2d_bits,24
2927 IgorA 2049
	jne @f
1535 IgorA 2050
		mov eax,buf2d_w
2051
		mov ecx,buf2d_h
2052
		imul ecx,eax
2053
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
2927 IgorA 2054
	@@:
2920 IgorA 2055
	cmp buf2d_bits,32
2927 IgorA 2056
	jne @f
2920 IgorA 2057
		mov eax,buf2d_w
2058
		mov ecx,buf2d_h
2059
		imul ecx,eax
2927 IgorA 2060
		stdcall img_rgba32_wdiv2, buf2d_data,ecx
2061
	@@:
1535 IgorA 2062
	popad
2063
	ret
2064
endp
2065
 
2066
;input:
2927 IgorA 2067
;data_8b - pointer to rgb data
2068
;size - count img pixels (size img data / 3(rgb) )
2069
align 4
2070
proc img_8b_wdiv2 data_8b:dword, size:dword
2071
	mov eax,dword[data_8b]
2072
	mov ecx,dword[size] ;ecx = size
2073
	cld
2074
	@@: ;затемнение цвета пикселей
2075
		shr byte[eax],1
2076
		inc eax
2077
		loop @b
2078
 
2079
	mov eax,dword[data_8b]
2080
	mov ecx,dword[size] ;ecx = size
2081
	shr ecx,1
2082
	@@: ;сложение цветов пикселей
2083
		mov bl,byte[eax+1] ;копируем цвет соседнего пикселя
2084
		add byte[eax],bl
2085
		add eax,2
2086
		loop @b
2087
 
2088
	mov eax,dword[data_8b]
2089
	inc eax
2090
	mov ebx,eax
2091
	inc ebx
2092
	mov ecx,dword[size] ;ecx = size
2093
	shr ecx,1
2094
	dec ecx ;лишний пиксель
2095
	@@: ;поджатие пикселей
2096
		mov dl,byte[ebx]
2097
		mov byte[eax],dl
2098
 
2099
		inc eax
2100
		add ebx,2
2101
		loop @b
2102
	ret
2103
endp
2104
 
2105
;input:
1535 IgorA 2106
;data_rgb - pointer to rgb data
2107
;size - count img pixels (size img data / 3(rgb) )
2108
align 4
2109
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
2110
  mov eax,dword[data_rgb]
2111
  mov ecx,dword[size] ;ecx = size
2112
  lea ecx,[ecx+ecx*2]
2113
  cld
2114
  @@: ;затемнение цвета пикселей
1538 IgorA 2115
		shr byte[eax],1
2116
		inc eax
2117
		loop @b
1535 IgorA 2118
 
2119
  mov eax,dword[data_rgb]
2120
  mov ecx,dword[size] ;ecx = size
2121
  shr ecx,1
2122
  @@: ;сложение цветов пикселей
1538 IgorA 2123
		mov bx,word[eax+3] ;копируем цвет соседнего пикселя
2124
		add word[eax],bx
2125
		mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
2126
		add byte[eax+2],bl
2127
		add eax,6 ;=2*3
2128
		loop @b
1535 IgorA 2129
 
2130
  mov eax,dword[data_rgb]
2131
  add eax,3
2132
  mov ebx,eax
2133
  add ebx,3
2134
  mov ecx,dword[size] ;ecx = size
2135
  shr ecx,1
2136
  dec ecx ;лишний пиксель
2137
  @@: ;поджатие пикселей
1538 IgorA 2138
		mov edx,dword[ebx]
2139
		mov word[eax],dx
2140
		shr edx,16
2141
		mov byte[eax+2],dl
1535 IgorA 2142
 
1538 IgorA 2143
		add eax,3
2144
		add ebx,6
2145
		loop @b
1535 IgorA 2146
  ret
2147
endp
2148
 
2920 IgorA 2149
;input:
2927 IgorA 2150
;data_rgba - pointer to rgba data
2151
;size - count img pixels (size img data / 4(rgba) )
1535 IgorA 2152
align 4
2927 IgorA 2153
proc img_rgba32_wdiv2 data_rgba:dword, size:dword
2154
	mov eax,dword[data_rgba]
2920 IgorA 2155
 
2927 IgorA 2156
	mov eax,dword[data_rgba]
2920 IgorA 2157
	mov ebx,eax
2158
	add ebx,4
2159
	mov ecx,dword[size] ;ecx = size
2160
	shr ecx,1
2161
	@@: ;смешивание цветов пикселей
2162
		call combine_colors_1
2163
		mov [eax],edx
2164
		add eax,8 ;=2*4
2165
		add ebx,8
2166
		loop @b
2167
 
2927 IgorA 2168
	mov eax,dword[data_rgba]
2920 IgorA 2169
	add eax,4
2170
	mov ebx,eax
2171
	add ebx,4
2172
	mov ecx,dword[size] ;ecx = size
2173
	shr ecx,1
2174
	dec ecx ;лишний пиксель
2175
	@@: ;поджатие пикселей
2176
		mov edx,dword[ebx]
2177
		mov dword[eax],edx
2178
 
2179
		add eax,4
2180
		add ebx,8
2181
		loop @b
2182
	ret
2183
endp
2184
 
3040 IgorA 2185
;description:
2186
; сжатие изображения по высоте (высота буфера не меняется)
2920 IgorA 2187
align 4
1535 IgorA 2188
proc buf_img_hdiv2, buf_struc:dword
2189
	pushad
2190
	mov edi,dword[buf_struc]
2927 IgorA 2191
	cmp buf2d_bits,8
2192
	jne @f
2193
		mov eax,buf2d_w
2194
		mov ecx,buf2d_h
2195
		imul ecx,eax
2196
		stdcall img_8b_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2197
		jmp .end_f ;edi портится в функции, потому использование buf2d_bits опасно
2927 IgorA 2198
	@@:
1535 IgorA 2199
	cmp buf2d_bits,24
2927 IgorA 2200
	jne @f
1535 IgorA 2201
		mov eax,buf2d_w
2202
		mov ecx,buf2d_h
2203
		imul ecx,eax
2204
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2205
		jmp .end_f
2927 IgorA 2206
	@@:
2920 IgorA 2207
	cmp buf2d_bits,32
2927 IgorA 2208
	jne @f
2920 IgorA 2209
		mov eax,buf2d_w
2210
		mov ecx,buf2d_h
2211
		imul ecx,eax
2212
		shl eax,2
2927 IgorA 2213
		stdcall img_rgba32_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2214
		;jmp .end_f
2927 IgorA 2215
	@@:
3040 IgorA 2216
	.end_f:
1535 IgorA 2217
	popad
2218
	ret
2219
endp
2220
 
2221
;input:
2927 IgorA 2222
;data_8b - pointer to 8 bit data
2223
;size - count img pixels (size img data)
2224
;size_w - width img in pixels
2225
align 4
2226
proc img_8b_hdiv2, data_8b:dword, size:dword, size_w:dword
2227
 
2228
	mov eax,dword[data_8b] ;eax =
2229
	mov ecx,dword[size]
2230
	cld
2231
	@@: ;затемнение цвета пикселей
2232
		shr byte[eax],1
2233
		inc eax
2234
		loop @b
2235
 
2236
	mov eax,dword[data_8b] ;eax =
2237
	mov esi,dword[size_w]
2238
	mov ebx,esi
2239
	add ebx,eax
2240
	mov ecx,dword[size]  ;ecx = size
2241
	shr ecx,1
2242
	xor edi,edi
2243
	@@: ;сложение цветов пикселей
2244
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
2245
		add byte[eax],dl
2246
 
2247
		inc eax
2248
		inc ebx
2249
		inc edi
2250
		cmp edi,dword[size_w]
2251
		jl .old_line
2252
			add eax,esi
2253
			add ebx,esi
2254
			xor edi,edi
2255
		.old_line:
2256
		loop @b
2257
 
2258
 
2259
	mov eax,dword[data_8b] ;eax =
2260
	add eax,esi ;esi = width*3(rgb)
2261
	mov ebx,eax
2262
	add ebx,esi
2263
	mov ecx,dword[size] ;ecx = size
2264
	shr ecx,1
2265
	sub ecx,dword[size_w] ;лишняя строка пикселей
2266
	xor edi,edi
2267
	@@: ;поджатие пикселей
2268
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
2269
		mov byte[eax],dl
2270
 
2271
		inc eax
2272
		inc ebx
2273
		inc edi
2274
		cmp edi,dword[size_w]
2275
		jl .old_line_2
2276
			add ebx,esi
2277
			xor edi,edi
2278
		.old_line_2:
2279
		loop @b
2280
 
2281
	ret
2282
endp
2283
 
2284
;input:
1535 IgorA 2285
;data_rgb - pointer to rgb data
2286
;size - count img pixels (size img data / 3(rgb) )
2287
;size_w - width img in pixels
2288
align 4
2289
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
2290
 
2291
  mov eax,dword[data_rgb] ;eax =
2292
  mov ecx,dword[size]	  ;ecx = size
2293
  lea ecx,[ecx+ecx*2]
2294
  cld
2295
  @@: ;затемнение цвета пикселей
2296
    shr byte[eax],1
2297
    inc eax
2298
    loop @b
2299
 
2300
  mov eax,dword[data_rgb] ;eax =
2920 IgorA 2301
  mov esi,dword[size_w]
2302
  lea esi,[esi+esi*2] ;esi = width*3(rgb)
1535 IgorA 2303
  mov ebx,esi
2304
  add ebx,eax
2305
  mov ecx,dword[size]  ;ecx = size
2306
  shr ecx,1
2307
  xor edi,edi
2308
  @@: ;сложение цветов пикселей
2309
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
2310
    add word[eax],dx
2311
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
2312
    add byte[eax+2],dl
2313
 
2314
    add eax,3
2315
    add ebx,3
2316
    inc edi
2317
    cmp edi,dword[size_w]
2318
    jl .old_line
2319
      add eax,esi
2320
      add ebx,esi
2321
      xor edi,edi
2322
    .old_line:
2323
    loop @b
2324
 
2325
 
2326
  mov eax,dword[data_rgb] ;eax =
2327
  add eax,esi ;esi = width*3(rgb)
2920 IgorA 2328
  mov ebx,eax
2329
  add ebx,esi
1535 IgorA 2330
  mov ecx,dword[size] ;ecx = size
2331
  shr ecx,1
2332
  sub ecx,dword[size_w] ;лишняя строка пикселей
2333
  xor edi,edi
2334
  @@: ;поджатие пикселей
2335
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
2336
    mov word[eax],dx
2337
    shr edx,16
2338
    mov byte[eax+2],dl
2339
 
2340
    add eax,3
2341
    add ebx,3
2342
    inc edi
2343
    cmp edi,dword[size_w]
2344
    jl .old_line_2
2345
      add ebx,esi
2346
      xor edi,edi
2347
    .old_line_2:
2348
    loop @b
2349
 
2350
  ret
2351
endp
2352
 
2920 IgorA 2353
;input:
2927 IgorA 2354
;data_rgba - pointer to rgba data
2355
;size - count img pixels (size img data / 4(rgba) )
2920 IgorA 2356
;size_w_b - width img in bytes
2357
align 4
2927 IgorA 2358
proc img_rgba32_hdiv2, data_rgba:dword, size:dword, size_w_b:dword
2920 IgorA 2359
 
2927 IgorA 2360
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 2361
	mov ebx,dword[size_w_b]
2362
	add ebx,eax
2363
	mov ecx,dword[size]  ;ecx = size
2364
	shr ecx,1
2365
	xor edi,edi
2366
	@@: ;смешивание цветов пикселей
2367
		call combine_colors_1
2368
		mov dword[eax],edx
2369
 
2370
		add eax,4
2371
		add ebx,4
2372
		add edi,4
2373
		cmp edi,dword[size_w_b]
2374
		jl .old_line
2375
			add eax,dword[size_w_b]
2376
			add ebx,dword[size_w_b]
2377
			xor edi,edi
2378
		.old_line:
2379
		loop @b
2380
 
2381
 
2927 IgorA 2382
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 2383
	mov ebx,dword[size_w_b]
2384
	add eax,ebx
2385
	add ebx,eax
2386
	mov ecx,dword[size] ;ecx = size
2387
	shl ecx,1
2388
	sub ecx,dword[size_w_b] ;лишняя строка пикселей
2389
	shr ecx,2
2390
	xor edi,edi
2391
	@@: ;поджатие пикселей
2392
		mov edx,dword[ebx] ;копируем цвет нижнего пикселя
2393
		mov dword[eax],edx
2394
 
2395
		add eax,4
2396
		add ebx,4
2397
		add edi,4
2398
		cmp edi,dword[size_w_b]
2399
		jl .old_line_2
2400
			add ebx,dword[size_w_b]
2401
			xor edi,edi
2402
		.old_line_2:
2403
		loop @b
2404
 
2405
	ret
2406
endp
2407
 
2408
;input:
2409
; eax - указатель на 32-битный цвет
2410
; ebx - указатель на 32-битный цвет
2411
;output:
2412
; edx - 32-битный цвет смешанный с учетом прозрачности
2413
;destroy:
2414
; esi
2415
align 4
2416
proc combine_colors_1 uses ecx edi
2417
locals
2418
	c_blye dd ?
2419
	c_green dd ?
2420
	c_red dd ?
2421
endl
2422
	movzx edi,byte[eax+3]
2423
	cmp edi,255
2424
	je .c0z
2425
	movzx esi,byte[ebx+3]
2426
	cmp esi,255
2427
	je .c1z
2927 IgorA 2428
	cmp edi,esi
2429
	je .c0_c1
2920 IgorA 2430
 
2431
	;переворачиваем значения прозрачностей
2432
	neg edi
2433
	inc edi
2434
	add edi,255
2435
	neg esi
2436
	inc esi
2437
	add esi,255
2438
 
2439
	movzx ecx,byte[eax]
2440
	imul ecx,edi
2441
	mov [c_blye],ecx
2442
	movzx ecx,byte[ebx]
2443
	imul ecx,esi
2444
	add [c_blye],ecx
2445
 
2446
	movzx ecx,byte[eax+1]
2447
	imul ecx,edi
2448
	mov [c_green],ecx
2449
	movzx ecx,byte[ebx+1]
2450
	imul ecx,esi
2451
	add [c_green],ecx
2452
 
2453
	movzx ecx,byte[eax+2]
2454
	imul ecx,edi
2455
	mov [c_red],ecx
2456
	movzx ecx,byte[ebx+2]
2457
	imul ecx,esi
2458
	add [c_red],ecx
2459
 
2460
push eax ebx
2461
	xor ebx,ebx
2462
	mov eax,[c_red]
2463
	xor edx,edx
2464
	mov ecx,edi
2465
	add ecx,esi
2466
	div ecx
2467
	mov bl,al
2468
	shl ebx,16
2469
	mov eax,[c_green]
2470
	xor edx,edx
2471
	div ecx
2472
	mov bh,al
2473
	mov eax,[c_blye]
2474
	xor edx,edx
2475
	div ecx
2476
	mov bl,al
2477
 
2478
	shr ecx,1
2479
	;переворачиваем значения прозрачности
2480
	neg ecx
2481
	inc ecx
2482
	add ecx,255
2483
 
2484
	shl ecx,24
2485
	add ebx,ecx
2486
	mov edx,ebx
2487
pop ebx eax
2488
 
2489
	jmp .end_f
2927 IgorA 2490
	.c0_c1: ;если прозрачности обоих цветов совпадают
2491
		mov edx,dword[eax]
2492
		shr edx,1
2493
		and edx,011111110111111101111111b
2494
		mov esi,dword[ebx]
2495
		shr esi,1
2496
		and esi,011111110111111101111111b
2497
		add edx,esi
2498
		ror edi,8 ;перемещаем значение прозрачности в старший байт edi
2499
		or edx,edi
2500
		jmp .end_f
2920 IgorA 2501
	.c0z: ;если цвет в eax прозрачный
2502
		mov edx,dword[ebx]
2503
		movzx edi,byte[ebx+3]
2504
		jmp @f
2505
	.c1z: ;если цвет в ebx прозрачный
2506
		mov edx,dword[eax]
2507
	@@:
2508
		add edi,255 ;делаем цвет на половину прозрачным
2509
		shr edi,1
2510
		cmp edi,255
2511
		jl @f
2512
			mov edi,255 ;максимальная прозрачность не более 255
2513
		@@:
2514
		shl edi,24
2515
		and edx,0xffffff ;снимаем старую прозрачность
2516
		add edx,edi
2517
	.end_f:
2518
	ret
2519
endp
2520
 
1535 IgorA 2521
;преобразование буфера из 24-битного в 8-битный
2522
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
2523
align 4
2524
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
2525
	pushad
2526
	mov edi,dword[buf_struc]
2527
	cmp buf2d_bits,24
2528
	jne .error
2529
		mov eax,buf2d_w
2530
		mov ecx,buf2d_h
2531
		imul ecx,eax
2532
		mov esi,ecx
2533
		;ebx - память из которой копируется
2534
		;edx - память куда копируется
2535
		mov edx,buf2d_data
2536
		mov ebx,edx
2537
		cmp [spectr],3
2538
		jge @f
2539
			add ebx,[spectr]
2540
		@@:
2541
			mov al,byte[ebx]
2542
			mov byte[edx],al
2543
			add ebx,3
2544
			inc edx
2545
			loop @b
2546
		mov buf2d_bits,8
2547
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
2548
		jmp .end_conv
2549
	.error:
2550
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
2551
	.end_conv:
2552
	popad
2553
	ret
2554
endp
2555
 
2556
;преобразование буфера из 24-битного в 32-битный
2557
align 4
2558
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
2559
	pushad
2560
	mov edi,dword[buf_struc]
2561
	cmp buf2d_bits,24
2562
	jne .error1
2563
		mov ecx,buf2d_w
2564
		mov ebx,buf2d_h
2565
		imul ebx,ecx
2566
		mov ecx,ebx ;ecx = size  8 b
2567
		shl ebx,2   ;ebx = size 32 b
2568
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
2569
		mov buf2d_data,eax ;на случай если изменился указатель на данные
2570
		mov buf2d_bits,32
2571
		mov edx,ebx ;edx = size 32 b
2572
		sub ebx,ecx ;ebx = size 24 b
2573
		mov eax,ecx
2574
		;eax - размер  8 битных данных
2575
		;ebx - размер 24 битных данных
2576
		;edx - размер 32 битных данных
2577
		add ebx,buf2d_data
2578
		add edx,buf2d_data
2579
		mov edi,dword[buf_str8]
2580
		cmp buf2d_bits,8
2581
		jne .error2
2582
		add eax,buf2d_data
2583
		mov edi,edx
2584
		;eax - указатель на конец  8 битных данных
2585
		;ebx - указатель на конец 24 битных данных
2586
		;edi - указатель на конец 32 битных данных
2587
		@@:
2588
			sub edi,4 ;отнимаем в начале цикла,
2589
			sub ebx,3 ; потому, что указатели стоят
2590
			dec eax   ; за пределами буферов
2591
			mov edx,dword[ebx]
2592
			mov dword[edi],edx
2593
			mov dl,byte[eax]
2594
			mov byte[edi+3],dl
2595
			loop @b
2596
 
2597
		jmp .end_conv
2598
	.error1:
2599
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
2600
		jmp .end_conv
2601
	.error2:
2602
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
2603
	.end_conv:
2604
	popad
2605
	ret
2606
endp
2607
 
2608
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
2609
; указываются координаты вставки буфера buf_source относительно buf_destination
2610
; прозрачность при копировании не учитывается
2611
align 4
2612
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2613
	locals
2614
		right_bytes dd ?
2615
	endl
2616
	pushad
2617
 
2618
	mov edi,[buf_source]
2619
	cmp buf2d_bits,24
2620
	je .sou24
2621
	cmp buf2d_bits,32
2622
	je .sou32
2623
		jmp .copy_end ;формат буфера не поодерживается
2624
 
1648 IgorA 2625
	.sou24: ;в источнике 24 битная картинка
1535 IgorA 2626
	mov eax,buf2d_w
2627
	mov edx,buf2d_h ;высота копируемой картинки
2628
	mov esi,buf2d_data ;данные копируемой картинки
2629
 
2630
	mov edi,[buf_destination]
2631
	cmp buf2d_bits,24
2632
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2633
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2634
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2635
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2636
		mov ebx,buf2d_h ;ebx - высота основного буфера
2637
		mov ecx,[coord_y]
2422 IgorA 2638
		cmp ecx,0
2639
		jge @f
2640
			;если координата coord_y<0 (1-я настройка)
2641
			add edx,ecx ;уменьшаем высоту копируемой картинки
2642
			cmp edx,0
2643
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2644
			neg ecx
2645
			;inc ecx
2646
			imul ecx,eax
2647
			lea ecx,[ecx+ecx*2] ;по 3 байта на пиксель
2648
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2649
			xor ecx,ecx ;обнуляем координату coord_y
2650
		@@:
1535 IgorA 2651
		cmp ecx,ebx
2652
		jge .copy_end ;если координата 'y' больше высоты буфера
2653
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2654
		cmp ecx,ebx
2655
		jle @f
2656
			sub ecx,ebx
2657
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2658
		@@:
2659
		mov ebx,buf2d_w
2422 IgorA 2660
		mov ecx,[coord_y] ;ecx используем для временных целей
2661
		cmp ecx,0
2662
		jg .end_otr_c_y_24
2663
			;если координата coord_y<=0 (2-я настройка)
2664
			mov ecx,[coord_x]
2665
			jmp @f
2666
		.end_otr_c_y_24:
2667
		imul ecx,ebx
1535 IgorA 2668
		add ecx,[coord_x]
2422 IgorA 2669
		@@:
1535 IgorA 2670
		lea ecx,[ecx+ecx*2]
2671
		add ecx,buf2d_data
2672
		sub ebx,eax
2673
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2674
 
2675
	mov [right_bytes],0
2676
	mov ecx,[coord_x]
2677
	cmp ecx,ebx
2678
	jl @f
2679
		sub ecx,ebx
2680
		sub eax,ecx ;укорачиваем копируемую строку
2681
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2682
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2683
		mov [right_bytes],ecx
2684
	@@:
2685
 
2686
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
2687
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2688
 
2689
	cld
2690
	cmp [right_bytes],0
2691
	jg .copy_1
2692
	.copy_0: ;простое копирование
2693
		mov ecx,eax
2694
		rep movsb
2695
		add edi,ebx
2696
		dec edx
2697
		cmp edx,0
2698
		jg .copy_0
2699
	jmp .copy_end
2700
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2701
		mov ecx,eax
2702
		rep movsb
2703
		add edi,ebx
2704
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2705
		dec edx
2706
		cmp edx,0
2707
		jg .copy_1
2708
	jmp .copy_end
2709
 
2710
	.sou32: ;в источнике 32 битная картинка
2711
	mov eax,buf2d_w
2712
	mov edx,buf2d_h ;высота копируемой картинки
2713
	mov esi,buf2d_data ;данные копируемой картинки
2714
 
2715
	mov edi,[buf_destination]
2716
	cmp buf2d_bits,24
2717
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2718
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2719
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2720
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2721
		mov ebx,buf2d_h ;ebx - высота основного буфера
2722
		mov ecx,[coord_y]
2422 IgorA 2723
		cmp ecx,0
2724
		jge @f
2725
			;если координата coord_y<0 (1-я настройка)
2726
			add edx,ecx ;уменьшаем высоту копируемой картинки
2727
			cmp edx,0
2728
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2729
			neg ecx
2730
			;inc ecx
2731
			imul ecx,eax
2732
			shl ecx,2 ;по 4 байта на пиксель
2733
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2734
			xor ecx,ecx ;обнуляем координату coord_y
2735
		@@:
1535 IgorA 2736
		cmp ecx,ebx
2737
		jge .copy_end ;если координата 'y' больше высоты буфера
2738
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2739
		cmp ecx,ebx
2740
		jle @f
2741
			sub ecx,ebx
2742
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2743
		@@:
2744
		mov ebx,buf2d_w
2422 IgorA 2745
		;mov ecx,ebx ;ecx используем для временных целей
2746
		;imul ecx,[coord_y]
2747
		;add ecx,[coord_x]
2748
		mov ecx,[coord_y] ;ecx используем для временных целей
2749
		cmp ecx,0
2750
		jg .end_otr_c_y_32
2751
			;если координата coord_y<=0 (2-я настройка)
2752
			mov ecx,[coord_x]
2753
			jmp @f
2754
		.end_otr_c_y_32:
2755
		imul ecx,ebx
1535 IgorA 2756
		add ecx,[coord_x]
2422 IgorA 2757
		@@:
1535 IgorA 2758
		lea ecx,[ecx+ecx*2]
2759
		add ecx,buf2d_data
2760
		sub ebx,eax
2761
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2762
 
2763
	mov [right_bytes],0
2764
	mov ecx,[coord_x]
2765
	cmp ecx,ebx
2766
	jl @f
2767
		sub ecx,ebx
2768
		sub eax,ecx ;укорачиваем копируемую строку
2769
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2770
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2771
		mov [right_bytes],ecx
2772
	@@:
2773
 
2774
	;eax - колличество пикселей в 1-й строке копируемой картинки
2775
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2776
 
2777
	cld
2778
	cmp [right_bytes],0
2779
	jg .copy_3
2780
	.copy_2: ;простое копирование
2781
		mov ecx,eax
2782
		@@:
2783
			movsw
2784
			movsb
2785
			inc esi
2786
			loop @b
2787
		add edi,ebx
2788
		dec edx
2789
		cmp edx,0
2790
		jg .copy_2
2791
	jmp .copy_end
2792
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
2793
		mov ecx,eax
2794
		@@:
2795
			movsw
2796
			movsb
2797
			inc esi
2798
			loop @b
2799
		add edi,ebx
2800
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2801
		dec edx
2802
		cmp edx,0
2803
		jg .copy_3
2804
 
2805
	.copy_end:
2806
	popad
2807
	ret
2808
endp
2809
 
2810
;input:
2811
; esi = pointer to color1 + transparent
2812
; edi = pointer to background color2
2813
;output:
2814
; [edi] = combine color
2815
align 4
2920 IgorA 2816
combine_colors_0:
1535 IgorA 2817
	push ax bx cx dx
2818
	mov bx,0x00ff ;---get transparent---
2748 IgorA 2819
	movzx cx,byte[esi+3] ;pro
1535 IgorA 2820
	sub bx,cx ;256-pro
1653 IgorA 2821
	;---blye---
2748 IgorA 2822
	movzx ax,byte[esi]
1535 IgorA 2823
	imul ax,bx
2748 IgorA 2824
	movzx dx,byte[edi]
1535 IgorA 2825
	imul dx,cx
2826
	add ax,dx
1653 IgorA 2827
	mov byte[edi],ah
1535 IgorA 2828
	;---green---
2748 IgorA 2829
	movzx ax,byte[esi+1]
1535 IgorA 2830
	imul ax,bx
2748 IgorA 2831
	movzx dx,byte[edi+1]
1535 IgorA 2832
	imul dx,cx
2833
	add ax,dx
2834
	mov byte[edi+1],ah
1653 IgorA 2835
	;---red---
2748 IgorA 2836
	movzx ax,byte[esi+2]
1535 IgorA 2837
	imul ax,bx
2748 IgorA 2838
	movzx dx,byte[edi+2]
1535 IgorA 2839
	imul dx,cx
2840
	add ax,dx
1653 IgorA 2841
	mov byte[edi+2],ah
1535 IgorA 2842
 
2843
	pop dx cx bx ax
2844
	ret
2845
 
2846
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
2847
; указываются координаты вставки буфера buf_source относительно buf_destination
2848
; при копировании учитывается прозрачность
2849
align 4
2850
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2851
	locals
2927 IgorA 2852
		lost_bytes dd ?
1535 IgorA 2853
	endl
2854
	pushad
2855
 
2856
	mov edi,[buf_source]
2857
	cmp buf2d_bits,32
2858
	jne .copy_end ;формат буфера не поодерживается
2859
	mov eax,buf2d_w
2860
	mov edx,buf2d_h ;высота копируемой картинки
2861
	mov esi,buf2d_data ;данные копируемой картинки
2862
 
2863
	mov edi,[buf_destination]
2864
	cmp buf2d_bits,24
2865
	jne .copy_end ;формат буфера не поодерживается
2866
		mov ebx,buf2d_h ;ebx - высота основного буфера
2867
		mov ecx,[coord_y]
2383 IgorA 2868
		cmp ecx,0
2869
		jge @f
2870
			;если координата coord_y<0 (1-я настройка)
2871
			add edx,ecx ;уменьшаем высоту копируемой картинки
2872
			cmp edx,0
2873
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2874
			neg ecx
2875
			;inc ecx
2876
			imul ecx,eax
2422 IgorA 2877
			shl ecx,2 ;по 4 байта на пиксель
2383 IgorA 2878
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2879
			xor ecx,ecx ;обнуляем координату coord_y
2880
		@@:
1535 IgorA 2881
		cmp ecx,ebx
2882
		jge .copy_end ;если координата 'y' больше высоты буфера
2883
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2884
		cmp ecx,ebx
2885
		jle @f
2886
			sub ecx,ebx
2887
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2888
		@@:
2889
		mov ebx,buf2d_w
2890
		mov ecx,ebx ;ecx используем для временных целей
2383 IgorA 2891
		cmp [coord_y],0
2892
		jg .end_otr_c_y
2893
			;если координата coord_y<=0 (2-я настройка)
2894
			mov ecx,[coord_x]
2895
			jmp @f
2896
		.end_otr_c_y:
1535 IgorA 2897
		imul ecx,[coord_y]
2898
		add ecx,[coord_x]
2383 IgorA 2899
		@@:
1535 IgorA 2900
		lea ecx,[ecx+ecx*2]
2901
		add ecx,buf2d_data
2902
		sub ebx,eax
2903
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2904
 
2927 IgorA 2905
	mov dword[lost_bytes],0
1535 IgorA 2906
	mov ecx,[coord_x]
2927 IgorA 2907
	cmp ecx,0
2908
	jge @f
2909
		neg ecx
2910
		;inc ecx
2911
		cmp eax,ecx ;eax - ширина копируемой картинки
2912
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2913
		shl ecx,2
2914
		mov [lost_bytes],ecx
2915
		add esi,ecx
2916
		shr ecx,2
2917
		sub eax,ecx ;укорачиваем копируемую строку
2918
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2919
		lea ecx,[ecx+ecx*2]
2920
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2921
		xor ecx,ecx
2922
	@@:
1535 IgorA 2923
	cmp ecx,ebx
2927 IgorA 2924
	jle @f
1535 IgorA 2925
		sub ecx,ebx
2926
		sub eax,ecx ;укорачиваем копируемую строку
2927
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2927 IgorA 2928
		shl ecx,2 ;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2929
		add [lost_bytes],ecx
1535 IgorA 2930
	@@:
2931
 
2927 IgorA 2932
;	mov [right_bytes],0
2933
;	mov ecx,[coord_x]
2934
;	cmp ecx,ebx
2935
;	jl @f
2936
;		sub ecx,ebx
2937
;		sub eax,ecx ;укорачиваем копируемую строку
2938
;		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2939
;		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2940
;		mov [right_bytes],ecx
2941
;	@@:
2942
 
1535 IgorA 2943
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2658 IgorA 2944
 
1535 IgorA 2945
	cld
2927 IgorA 2946
	cmp [lost_bytes],0
1535 IgorA 2947
	jg .copy_1
2948
	.copy_0: ;простое копирование
2949
		mov ecx,eax
2950
		@@:
2920 IgorA 2951
			call combine_colors_0
1535 IgorA 2952
			add edi,3
2953
			add esi,4
2954
			loop @b
2955
		add edi,ebx
2956
		dec edx
2957
		cmp edx,0
2958
		jg .copy_0
2959
	jmp .copy_end
2960
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2961
		mov ecx,eax
2962
		@@:
2920 IgorA 2963
			call combine_colors_0
1535 IgorA 2964
			add edi,3
2965
			add esi,4
2966
			loop @b
2967
		add edi,ebx
2927 IgorA 2968
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 2969
		dec edx
2970
		cmp edx,0
2971
		jg .copy_1
2972
 
2973
	.copy_end:
2974
	popad
2975
	ret
2976
endp
2977
 
2978
;input:
2979
; ebx - color1
2980
; esi = pointer to transparent
2981
; edi = pointer to background color2
2982
;output:
2983
; [edi] = combine color
2984
align 4
2985
combine_colors_2:
2986
	push ax ebx cx dx si
2987
	mov cl,byte[esi] ;pro
2988
	xor ch,ch
2989
	mov si,0x00ff ;---get transparent---
2990
	sub si,cx ;256-pro
2991
 
1653 IgorA 2992
		;---blye---
2748 IgorA 2993
		movzx ax,bl
1535 IgorA 2994
		shr ebx,8
2995
		imul ax,si
2748 IgorA 2996
		movzx dx,byte[edi]
1535 IgorA 2997
		imul dx,cx
2998
		add ax,dx
1653 IgorA 2999
		mov byte[edi],ah
1535 IgorA 3000
		;---green---
2748 IgorA 3001
		movzx ax,bl
1535 IgorA 3002
		shr ebx,8
3003
		imul ax,si
2748 IgorA 3004
		movzx dx,byte[edi+1]
1535 IgorA 3005
		imul dx,cx
3006
		add ax,dx
3007
		mov byte[edi+1],ah
3008
		;---red---
2748 IgorA 3009
		movzx ax,bl
1535 IgorA 3010
		imul ax,si
2748 IgorA 3011
		movzx dx,byte[edi+2]
1535 IgorA 3012
		imul dx,cx
3013
		add ax,dx
1653 IgorA 3014
		mov byte[edi+2],ah
1535 IgorA 3015
 
3016
	pop si dx cx ebx ax
3017
	ret
3018
 
3019
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
3020
; указываются координаты вставки буфера buf_source относительно buf_destination
3021
align 4
3022
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
3023
	locals
2383 IgorA 3024
		lost_bytes dd ? ;число потерянных байтов в строке копируемого изображеня (тех что не влазят в буфер)
1535 IgorA 3025
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
3026
	endl
3027
	pushad
3028
 
3029
	mov edi,[buf_source]
3030
	cmp buf2d_bits,8
3031
	jne .error1 ;формат буфера не поодерживается
2383 IgorA 3032
	mov eax,buf2d_w ;ширина копируемой картинки
1535 IgorA 3033
	mov edx,buf2d_h ;высота копируемой картинки
3034
	mov esi,buf2d_data ;данные копируемой картинки
3035
 
3036
	mov edi,[buf_destination]
3037
	cmp buf2d_bits,24
3038
	jne .error2 ;формат буфера не поодерживается
1642 IgorA 3039
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
3040
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 3041
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 3042
		mov ebx,buf2d_h ;ebx - высота основного буфера
3043
		mov ecx,[coord_y]
2367 IgorA 3044
		cmp ecx,0
3045
		jge @f
3046
			;если координата coord_y<0 (1-я настройка)
3047
			add edx,ecx ;уменьшаем высоту копируемой картинки
2383 IgorA 3048
			cmp edx,0
3049
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2367 IgorA 3050
			neg ecx
3051
			;inc ecx
3052
			imul ecx,eax
3053
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
3054
			xor ecx,ecx ;обнуляем координату coord_y
3055
		@@:
1535 IgorA 3056
		cmp ecx,ebx
3057
		jge .copy_end ;если координата 'y' больше высоты буфера
3058
		add ecx,edx ;ecx - нижняя координата копируемой картинки
3059
		cmp ecx,ebx
3060
		jle @f
3061
			sub ecx,ebx
3062
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
3063
		@@:
3064
		mov ebx,buf2d_w
2367 IgorA 3065
		mov ecx,[coord_y] ;ecx используем для временных целей
3066
		cmp ecx,0
2383 IgorA 3067
		jg .end_otr_c_y
3068
			;если координата coord_y<=0 (2-я настройка)
2367 IgorA 3069
			mov ecx,[coord_x]
3070
			jmp @f
3071
		.end_otr_c_y:
3072
		imul ecx,ebx
1535 IgorA 3073
		add ecx,[coord_x]
2367 IgorA 3074
		@@:
1535 IgorA 3075
		lea ecx,[ecx+ecx*2]
2383 IgorA 3076
		add ecx,buf2d_data ;buf2d_data данные основного буфера
3077
		sub ebx,eax ;ebx - ширина основного буфера минус ширина рисуемого буфера
1535 IgorA 3078
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3079
 
2383 IgorA 3080
	mov dword[lost_bytes],0
1535 IgorA 3081
	mov ecx,[coord_x]
2383 IgorA 3082
	cmp ecx,0
3083
	jge @f
3084
		neg ecx
3085
		;inc ecx
3086
		cmp eax,ecx ;eax - ширина копируемой картинки
3087
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2927 IgorA 3088
		mov [lost_bytes],ecx
2383 IgorA 3089
		sub eax,ecx ;укорачиваем копируемую строку
3090
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3091
		add esi,ecx
3092
		lea ecx,[ecx+ecx*2]
3093
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3094
		xor ecx,ecx
3095
	@@:
1535 IgorA 3096
	cmp ecx,ebx
2383 IgorA 3097
	jle @f
1535 IgorA 3098
		sub ecx,ebx
3099
		sub eax,ecx ;укорачиваем копируемую строку
3100
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3101
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2383 IgorA 3102
		add [lost_bytes],ecx
1535 IgorA 3103
	@@:
3104
 
3105
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
3106
	mov [dest_w_bytes],ebx
3107
	mov ebx,[color]
3108
 
3109
	cld
2383 IgorA 3110
	cmp dword[lost_bytes],0
1535 IgorA 3111
	jg .copy_1
3112
	.copy_0: ;простое копирование
3113
		mov ecx,eax
3114
		@@:
3115
			call combine_colors_2
3116
			add edi,3
3117
			inc esi
3118
			loop @b
3119
		add edi,[dest_w_bytes]
3120
		dec edx
3121
		cmp edx,0
3122
		jg .copy_0
3123
	jmp .copy_end
2383 IgorA 3124
	.copy_1: ;не простое копирование (картинка вылазит за левую и/или правую сторону)
1535 IgorA 3125
		mov ecx,eax
3126
		@@:
3127
			call combine_colors_2
3128
			add edi,3
3129
			inc esi
3130
			loop @b
3131
		add edi,[dest_w_bytes]
2383 IgorA 3132
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 3133
		dec edx
3134
		cmp edx,0
3135
		jg .copy_1
3136
 
3137
	jmp .copy_end
3138
	.error1:
3139
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
3140
		jmp .copy_end
3141
	.error2:
3142
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
3143
	.copy_end:
3144
	popad
3145
	ret
3146
endp
3147
 
3148
;преобразование 8-битного буфера размером 16*16 в размер 1*256 символов
3149
align 4
3150
proc buf_convert_text_matrix, buf_struc:dword
3151
	locals
3152
		tmp_mem dd ?
3153
		c1 dw ?
3154
		c2 dd ?
3155
		c3 dw ?
3156
	endl
3157
	pushad
3158
	mov edi,dword[buf_struc]
3159
	cmp buf2d_bits,8
3160
	jne .error
3161
		mov ecx,buf2d_h
3162
		mov ebx,ecx
3163
		shr ebx,4 ;предполагаем что в буфере 16 строк с символами, потому делим на 2^4
3164
		mov edx,buf2d_w
3165
		imul ecx,edx ;ecx = size  8 b
3166
		invoke mem.alloc,ecx ;выделяем временную память
3167
		mov [tmp_mem],eax ;eax - new memory
3168
 
3169
		shr edx,4 ;предполагаем что в буфере 16 колонок с символами, потому делим на 2^4
3170
		mov eax,ebx
3171
		imul ebx,edx ;вычисляем кооличество пикселей на 1 символ
3172
		;eax = bhe - высота буквы
3173
		;ebx = bwi*bhe - колличество пикселей в 1-й букве
3174
		;edx = bwi - ширина буквы
3175
		;ecx,esi,edi - используются в цикле .c_0
3176
		shr buf2d_w,4
3177
		shl buf2d_h,4 ;преобразовываем размеры буфера
3178
 
3179
		cld
3180
		mov esi,buf2d_data
3181
		mov edi,[tmp_mem]
3182
		mov word[c3],16
3183
		.c_3:
3184
			mov dword[c2],eax
3185
			.c_2:
3186
				mov word[c1],16
3187
				.c_1:
3188
					mov ecx,edx ;.c_0:
3189
					rep movsb
3190
					add edi,ebx
3191
					sub edi,edx ;edi+=(bwi*bhe-bwi)
3192
					dec word[c1]
3193
					cmp word[c1],0
3194
					jg .c_1
3195
				add edi,edx
3196
				shl ebx,4
3197
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
3198
				shr ebx,4
3199
				dec dword[c2]
3200
				cmp dword[c2],0
3201
				jg .c_2
3202
			sub edi,ebx
3203
			shl ebx,4
3204
			add edi,ebx ;edi+=(15*bwi*bhe)
3205
			shr ebx,4
3206
			dec word[c3]
3207
			cmp word[c3],0
3208
			jg .c_3
3209
 
3210
		mov edi,dword[buf_struc] ;копирование новой матрицы в основной буфер
3211
		mov edi,buf2d_data
3212
		mov esi,[tmp_mem]
3213
		mov ecx,ebx
3214
		shl ecx,8
3215
		rep movsb
3216
		invoke mem.free,[tmp_mem] ;чистим временную память
3217
		jmp .end_conv
3218
	.error:
3219
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
3220
	.end_conv:
3221
	popad
3222
	ret
3223
endp
3224
 
3225
align 4
3226
buf_s_matr buf_2d_header ? ;локальная матрица символа
3227
 
3228
align 4
3229
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
3230
	locals
3231
		buf_t_matr_offs dd ?
3232
	endl
3233
	pushad
3234
	mov edi,dword[buf_struc]
3235
	cmp buf2d_bits,24
3236
	jne .error2
3237
	mov edi,dword[buf_t_matr]
3238
	cmp buf2d_bits,8
3239
	jne .error1
3240
		mov edx,buf2d_data
3241
		mov [buf_t_matr_offs],edx
3242
		mov ecx,BUF_STRUCT_SIZE ;копируем структуру текстовой матрицы
3243
		mov esi,edi
3244
		lea edi,[buf_s_matr]
3245
		cld
3246
		rep movsb
3247
		lea edi,[buf_s_matr]
3248
		shr buf2d_h,8 ;делим высоту символьного буфера на 256, для нахождения высоты 1-го символа
3249
		mov ebx,buf2d_h ;берем высоту символа
3250
		mov ecx,buf2d_w ;берем ширину символа
3251
 
3252
		mov eax,[coord_x]
3253
		mov esi,[text]
3254
		cmp byte[esi],0
3255
		je .end_draw ;если пустая строка
3256
		@@:
3257
			xor edx,edx
3258
			mov dl,byte[esi] ;берем код символа
3259
			imul edx,ebx ;умножаем его на высоту символа
3260
			imul edx,ecx ;умножаем на ширину символа
3261
			add edx,[buf_t_matr_offs] ;прибавляем смещение 0-го символа, т. е. получается смещение выводимого символа
3262
			mov buf2d_data,edx ;в локальный буфер символа, ставим указатель на нужный символ из буфера buf_t_matr
3263
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
3264
			add eax,ecx
3265
			.new_s:
3266
				inc esi
3267
				cmp byte[esi],13
3268
				jne .no_13
3269
					mov eax,[coord_x]
3270
					add [coord_y],ebx
3271
					jmp .new_s
3272
				.no_13:
3273
			cmp byte[esi],0
3274
			jne @b
3275
		jmp .end_draw
3276
	.error1:
3277
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
3278
		jmp .end_draw
3279
	.error2:
3280
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
3281
	.end_draw:
3282
	popad
3283
	ret
3284
endp
3285
 
3286
align 4
3287
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
3288
	pushad
3289
	mov eax,63
3290
	mov ebx,1
3291
 
3292
	mov esi,[fun]
3293
	@@:
3294
		mov cl,byte[esi]
3295
		int 0x40
3296
		inc esi
3297
		cmp byte[esi],0
3298
		jne @b
3299
	mov cl,':'
3300
	int 0x40
3301
	mov cl,' '
3302
	int 0x40
3303
	mov esi,[mes]
3304
	@@:
3305
		mov cl,byte[esi]
3306
		int 0x40
3307
		inc esi
3308
		cmp byte[esi],0
3309
		jne @b
3310
	popad
3311
	ret
3312
endp
3313
 
3314
;input:
3315
; ebp+8  = p0
3316
; ebp+12 = p1
3317
align 4
3318
line_len4i:
3319
	push ebp
3320
	mov ebp,esp
3321
		finit
3322
		fild word [ebp+8]
3323
		fisub word [ebp+12]
3324
		fmul st0,st0 ;st0=x^2
3325
		fild word [ebp+10]
3326
		fisub word [ebp+14]
3327
		fmul st0,st0 ;st0=y^2
3328
		fadd st0,st1
3329
		fsqrt
3330
		fstp dword [ebp+12]
3331
	pop ebp
3332
	ret 4 ;8
3333
 
3334
align 4
1727 IgorA 3335
proc buf_curve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
1535 IgorA 3336
	locals
3337
		delt_t dd ?
3338
		opr_param dd ?
3339
		v_poi_0 dd ?
3340
	endl
3341
	pushad
3342
 
3343
;float t, xt,yt;
3344
;for(t=.0;t<1.;t+=.005){
3345
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
3346
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
3347
;  dc.SetPixel(xt,yt,255L);
3348
;}
3349
 
1727 IgorA 3350
	mov edx,[color] ;set curve color
1535 IgorA 3351
	mov edi,[buffer]
3352
	xor ebx,ebx
3353
	xor ecx,ecx
3354
 
3355
	finit
3356
 
3357
	; calculate delta t
3358
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
3359
	fadd dword[esp]
3360
	add esp,4 ;pop ...
3361
 
3362
	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
3363
	fadd dword[esp]
3364
	add esp,4 ;pop ...
3365
 
3366
	fadd st0,st0 ; len*=2
3367
	ftst
3368
	fstsw ax
3369
 
3370
	fld1
3371
	sahf
3372
	jle @f ;избегаем деления на 0
3373
		fdiv st0,st1
3374
	@@:
3375
	fstp dword[delt_t]
3376
 
3377
	finit
3378
 
3379
	;fild word[coord_p2+2] ;y2
3380
	fild word[coord_p1+2] ;y1
3381
	fild word[coord_p0+2] ;y0
3382
	fild word[coord_p2] ;x2
3383
	fild word[coord_p1] ;x1
3384
	fild word[coord_p0] ;x0
3385
	fld dword[delt_t]
3386
	fldz ;t=.0
3387
 
3388
	@@:
3389
		fld1
3390
		fsub st0,st1 ;1.-t
3391
		fmul st0,st0 ;pow(1.-t,2)
3392
		fmul st0,st3 ;...*x0
3393
		fstp dword[opr_param]
3394
 
3395
		fld1
3396
		fsub st0,st1 ;1.-t
3397
		fmul st0,st1 ;(1.-t)*t
3398
		fadd st0,st0
3399
		fmul st0,st4 ;...*x1
3400
		mov esi,dword[opr_param]
3401
		fstp dword[opr_param]
3402
 
3403
		fldz
3404
		fadd st0,st1 ;0+t
3405
		fmul st0,st0 ;t*t
3406
		fmul st0,st5 ;...*x2
3407
 
3408
		fadd dword[opr_param]
3409
		mov dword[opr_param],esi
3410
		fadd dword[opr_param]
3411
		fistp word[v_poi_0] ;x
3412
 
3413
		fld1
3414
		fsub st0,st1 ;1.-t
3415
		fmul st0,st0 ;pow(1.-t,2)
3416
		fmul st0,st6 ;...*y0
3417
		fstp dword[opr_param]
3418
 
3419
		fld1
3420
		fsub st0,st1 ;1.-t
3421
		fmul st0,st1 ;(1.-t)*t
3422
		fadd st0,st0
3423
		fmul st0,st7 ;...*y1
3424
		mov esi,dword[opr_param]
3425
		fstp dword[opr_param]
3426
 
3427
		fldz
3428
		fadd st0,st1 ;0+t
3429
		fmul st0,st0 ;t*t
3430
		fimul word[coord_p2+2] ;...*y2
3431
 
3432
		fadd dword[opr_param]
3433
		mov dword[opr_param],esi
3434
		fadd dword[opr_param]
3435
		fistp word[v_poi_0+2] ;y
3436
 
3437
		mov eax,1
3438
		mov bx,word[v_poi_0+2]
3439
		mov cx,word[v_poi_0]
3440
		call draw_pixel
3441
 
3442
		fadd st0,st1 ;t+dt
3443
 
3444
		fld1
3445
		fcomp
3446
		fstsw ax
3447
		sahf
3448
	jae @b
3449
 
3450
	popad
3451
	ret
3452
endp
3453
 
3138 heavyiron 3454
;фильтр
3105 IgorA 3455
align 4
3456
proc buf_filter_dither, buffer:dword, algor:dword
3457
	pushad
3458
	mov edi,[buffer]
3459
	cmp buf2d_bits,24
3460
	jne .error
3461
		mov edx,buf2d_w
3462
		mov esi,buf2d_h
3463
		mov edi,buf2d_data
3464
;edi - pointer to 24bit bitmap
3465
;edx - x size
3466
;esi - y size
3138 heavyiron 3467
		lea   edx,[edx+edx*2]
3105 IgorA 3468
		imul  esi,edx
2748 IgorA 3469
 
3105 IgorA 3470
		;определяем какой алгоритм использовать
3471
		cmp dword[algor],0
3472
		jne @f
3473
			call dither_0
3474
			jmp .dither_end
3475
		@@:
3476
		cmp dword[algor],1
3477
		jne @f
3478
			call dither_1
3479
			jmp .dither_end
3480
		@@:
3138 heavyiron 3481
		cmp dword[algor],2
3482
		jne @f
3483
			call dither_2
3484
			jmp .dither_end
3485
		@@:
3486
		cmp dword[algor],3
3487
		jne @f
3488
			call dither_3
3489
			jmp .dither_end
3490
		@@:
3491
		call dither_4
3105 IgorA 3492
		jmp .dither_end
3493
	.error:
3494
		stdcall print_err,sz_buf2d_filter_dither,txt_err_n24b
3495
	.dither_end:
3496
	popad
3497
	ret
3498
endp
2748 IgorA 3499
 
3105 IgorA 3500
align 16
3138 heavyiron 3501
dither_0: ; Sierra Filter Lite algorithm
3105 IgorA 3502
newp_0:   ; Dithering cycle
3503
	xor   ebx,ebx ; At first threshold
3504
	movzx ecx,byte[edi]
3505
	cmp   cl,255
3506
	je    newp_0.next
3507
	test  cl,cl
3508
	jz    newp_0.next
3509
	jns   @f
3510
	dec   ebx
3511
	sub   ecx,255
3512
@@:
3513
	mov   [edi],bl               ; putpixel
3514
 
3515
	sar   ecx,1                  ; error/2
3516
	;adc   ecx,0                  ; round to integer
3517
 
3518
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3519
	add   eax,ecx                ; add error/2 to (x+1;y)
3520
	jge   @f                     ; check_overflow
3521
	xor   eax,eax
3522
	jmp   .ok
3523
@@:
3524
	cmp   eax,255
3525
	jle   .ok
3526
	or    al,255
3527
.ok:
3528
	mov   [edi+3],al             ; putpixel
3529
 
3530
	sar   ecx,1                  ; error/4
3531
	adc   ecx,0                  ; round to integer
3532
 
3533
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3534
	add   eax,ecx                ; add error/4 to (x-1;y+1)
3535
	jge   @f                     ; check_overflow
3536
	xor   eax,eax
3537
	jmp   .ok1
3538
@@:
3539
	cmp   eax,255
3540
	jle   .ok1
3541
	or    al,255
3542
.ok1:
3543
	mov   [edi+edx-3],al         ; putpixel
3544
 
3545
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3546
	add   eax,ecx                ; add error/4 to (x;y+1)
3547
	jge   @f                     ; check_overflow
3548
	xor   eax,eax
3549
	jmp   .ok2
3550
@@:
3551
	cmp   eax,255
3552
	jle   .ok2
3553
	or    al,255
3554
.ok2:
3555
	mov   [edi+edx],al           ; putpixel
3556
 
3557
.next:
3558
	inc   edi
3559
	dec   esi
3560
	jnz   newp_0
3561
	ret
3562
 
3563
align 16
3138 heavyiron 3564
dither_1: ; Floyd-Steinberg algorithm
3105 IgorA 3565
newp_1:   ; Dithering cycle
3566
	xor   ebx,ebx ; At first threshold
3567
	movzx ecx,byte[edi]
3568
	cmp   cl,255
3569
	je    newp_1.next
3570
	test  cl,cl
3571
	jz    newp_1.next
3572
	jns   @f
3573
	dec   ebx
3574
	sub   ecx,255
3575
@@:
3576
	mov   [edi],bl               ; putpixel
3577
 
3578
	sar   ecx,4                  ; error/16
3579
	adc   ecx,0                  ; round to integer
3580
	mov   ebx,ecx
3581
 
3582
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3583
	add   eax,ecx                ; add error/16 to (x+1;y+1)
3584
	jge   @f                     ; check_overflow
3585
	xor   eax,eax
3586
	jmp   .ok
3587
@@:
3588
	cmp   eax,255
3589
	jle   .ok
3590
	or    al,255
3591
.ok:
3592
	mov   [edi+edx+3],al         ;putpixel
3593
 
3594
	imul  ecx,3
3595
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3596
	add   eax,ecx                ; add 3*error/16 to (x-1;y+1)
3597
	jge   @f                     ; check_overflow
3598
	xor   eax,eax
3599
	jmp   .ok1
3600
@@:
3601
	cmp   eax,255
3602
	jle   .ok1
3603
	or    al,255
3604
.ok1:
3605
	mov   [edi+edx-3],al         ;putpixel
3606
 
3607
	mov   ecx,ebx
3608
	imul  ecx,5
3609
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3610
	add   eax,ecx                ; add 5*error/16 to (x;y+1)
3611
	jge   @f                     ; check_overflow
3612
	xor   eax,eax
3613
	jmp   .ok2
3614
@@:
3615
	cmp   eax,255
3616
	jle   .ok2
3617
	or    al,255
3618
.ok2:
3619
	mov   [edi+edx],al           ;putpixel
3620
 
3621
	mov   ecx,ebx
3622
	imul  ecx,7
3623
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3624
	add   eax,ecx                ; add 7*error/16 to (x+1;y)
3625
	jge   @f                     ; check_overflow
3626
	xor   eax,eax
3627
	jmp   .ok3
3628
@@:
3629
	cmp   eax,255
3630
	jle   .ok3
3631
	or    al,255
3632
.ok3:
3633
	mov   [edi+3],al             ;putpixel
3634
 
3635
.next:
3636
	inc  edi
3637
	dec  esi
3638
	jnz  newp_1
3639
	ret
3640
 
3641
align 16
3138 heavyiron 3642
dither_2: ; Burkes algorithm
3105 IgorA 3643
newp_2:   ; Dithering cycle
3644
	xor   ebx,ebx ; At first threshold
3645
	movsx ecx,byte[edi]
3646
	cmp   cl,255
3647
	je    newp_2.next
3648
	test  cl,cl
3649
	jz    newp_2.next
3650
	jns   @f
3651
	dec   ebx
3652
@@:
3653
	mov   [edi],bl               ; putpixel
3654
 
3655
	sar   ecx,2                  ; error/4
3656
	adc   ecx,0                  ; round to integer
3657
 
3658
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3659
	add   eax,ecx                ; add error/4 to (x+1;y)
3660
	jge   @f                     ; check_overflow
3661
	xor   eax,eax
3662
	jmp   .ok
3663
@@:
3664
	cmp   eax,255
3665
	jle   .ok
3666
	or    al,255
3667
.ok:
3668
	mov   [edi+3],al             ; putpixel
3669
 
3670
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3671
	add   eax,ecx                ; add error/4 to (x;y+1)
3672
	jge   @f                     ; check_overflow
3673
	xor   eax,eax
3674
	jmp   .ok1
3675
@@:
3676
	cmp   eax,255
3677
	jle   .ok1
3678
	or    al,255
3679
.ok1:
3680
	mov   [edi+edx],al           ; putpixel
3681
 
3682
	sar   ecx,1                  ; error/8
3683
	adc   ecx,0                  ; round to integer
3684
 
3685
	movzx eax,byte[edi+6]        ; pixel (x+2;y)
3686
	add   eax,ecx                ; add error/8 to (x+2;y)
3687
	jge   @f                     ; check_overflow
3688
	xor   eax,eax
3689
	jmp   .ok2
3690
@@:
3691
	cmp   eax,255
3692
	jle   .ok2
3693
	or    al,255
3694
.ok2:
3695
	mov   [edi+6],al             ; putpixel
3696
 
3697
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3698
	add   eax,ecx                ; add error/8 to (x-1;y+1)
3699
	jge   @f                     ; check_overflow
3700
	xor   eax,eax
3701
	jmp   .ok3
3702
@@:
3703
	cmp   eax,255
3704
	jle   .ok3
3705
	or    al,255
3706
.ok3:
3707
	mov   [edi+edx-3],al         ; putpixel
3708
 
3709
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3710
	add   eax,ecx                ; add error/8 to (x+1;y+1)
3711
	jge   @f                     ; check_overflow
3712
	xor   eax,eax
3713
	jmp   .ok4
3714
@@:
3715
	cmp   eax,255
3716
	jle   .ok4
3717
	or    al,255
3718
.ok4:
3719
	mov   [edi+edx+3],al         ; putpixel
3720
 
3721
	sar   ecx,1                  ; error/16
3722
	;adc   ecx,0                  ; round to integer
3723
 
3724
	movzx eax,byte[edi+edx-6]    ; pixel (x-2;y+1)
3725
	add   eax,ecx                ; add error/16 to (x-2;y+1)
3726
	jge   @f                     ; check_overflow
3727
	xor   eax,eax
3728
	jmp   .ok5
3729
@@:
3730
	cmp   eax,255
3731
	jle   .ok5
3732
	or    al,255
3733
.ok5:
3734
	mov   [edi+edx-6],al         ; putpixel
3735
 
3736
	movzx eax,byte[edi+edx+6]    ; pixel (x+2;y+1)
3737
	add   eax,ecx                ; add error/16 to (x+2;y+1)
3738
	jge   @f                     ; check_overflow
3739
	xor   eax,eax
3740
	jmp   .ok6
3741
@@:
3742
	cmp   eax,255
3743
	jle   .ok6
3744
	or    al,255
3745
.ok6:
3746
	mov   [edi+edx+6],al         ; putpixel
3747
 
3748
.next:
3749
	inc   edi
3750
	dec   esi
3751
	jnz   newp_2
3752
	ret
3753
 
3754
 
3138 heavyiron 3755
align 16
3756
dither_3:                        ; Heavyiron_mod algorithm
3757
 newp_3:                         ; Dithering cycle
3758
    xor   ebx,ebx                ; At first threshold
3759
    movzx ecx,byte[edi]
3760
    cmp   cl,255
3761
    je   .next
3762
    test  cl,cl
3763
    jz    .next
3764
    jns   @f
3765
    dec   ebx
3766
    sub   ecx,255
3767
  @@:
3768
    mov   [edi],bl               ; putpixel
3105 IgorA 3769
 
3138 heavyiron 3770
    sar   ecx,2                  ; error/4
3771
 
3772
    movzx eax,byte[edi+3]        ; pixel (x+1;y)
3773
    add   eax,ecx                ; add error/4 to (x+1;y)
3774
    jge   @f                     ; check_overflow
3775
    xor   eax,eax
3776
    jmp   .ok
3777
  @@:
3778
    cmp   eax,255
3779
    jle   .ok
3780
    or    al,255
3781
  .ok:
3782
    mov   [edi+3],al             ; putpixel
3783
 
3784
    movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3785
    add   eax,ecx                ; add error/4 to (x-1;y+1)
3786
    jge   @f                     ; check_overflow
3787
    xor   eax,eax
3788
    jmp   .ok1
3789
  @@:
3790
    cmp   eax,255
3791
    jle   .ok1
3792
    or    al,255
3793
  .ok1:
3794
    mov   [edi+edx-3],al         ; putpixel
3795
 
3796
    movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3797
    add   eax,ecx                ; add error/4 to (x;y+1)
3798
    jge   @f                     ; check_overflow
3799
    xor   eax,eax
3800
    jmp   .ok2
3801
  @@:
3802
    cmp   eax,255
3803
    jle   .ok2
3804
    or    al,255
3805
  .ok2:
3806
    mov   [edi+edx],al           ; putpixel
3807
 
3808
  .next:
3809
    inc   edi
3810
    dec   esi
3811
    jnz   newp_3
3812
    ret
3813
 
3814
align 16
3815
dither_4:                        ; Atkinson algorithm
3816
 newp_4:                         ; Dithering cycle
3817
 
3818
    xor   ebx,ebx                ; At first threshold
3819
    movsx ecx,byte[edi]
3820
    cmp   cl,255
3821
    je   .next
3822
    test  cl,cl
3823
    jz    .next
3824
    jns   @f
3825
    dec   ebx
3826
  @@:
3827
    mov   [edi],bl               ; putpixel
3828
 
3829
    sar   ecx,3                  ; error/8
3830
 
3831
    movzx eax,byte[edi+3]        ; pixel (x+1;y)
3832
    add   eax,ecx                ; add error/8 to (x+1;y)
3833
    jge   @f                     ; check_overflow
3834
    xor   eax,eax
3835
    jmp   .ok
3836
  @@:
3837
    cmp   eax,255
3838
    jle   .ok
3839
    or    al,255
3840
  .ok:
3841
    mov   [edi+3],al             ; putpixel
3842
 
3843
    movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3844
    add   eax,ecx                ; add error/8 to (x;y+1)
3845
    jge   @f                     ; check_overflow
3846
    xor   eax,eax
3847
    jmp   .ok1
3848
  @@:
3849
    cmp   eax,255
3850
    jle   .ok1
3851
    or    al,255
3852
  .ok1:
3853
    mov   [edi+edx],al           ; putpixel
3854
 
3855
    movzx eax,byte[edi+6]        ; pixel (x+2;y)
3856
    add   eax,ecx                ; add error/8 to (x+2;y)
3857
    jge   @f                     ; check_overflow
3858
    xor   eax,eax
3859
    jmp   .ok2
3860
  @@:
3861
    cmp   eax,255
3862
    jle   .ok2
3863
    or    al,255
3864
  .ok2:
3865
    mov   [edi+6],al             ; putpixel
3866
 
3867
    movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3868
    add   eax,ecx                ; add error/8 to (x-1;y+1)
3869
    jge   @f                     ; check_overflow
3870
    xor   eax,eax
3871
    jmp   .ok3
3872
  @@:
3873
    cmp   eax,255
3874
    jle   .ok3
3875
    or    al,255
3876
  .ok3:
3877
    mov   [edi+edx-3],al         ; putpixel
3878
 
3879
    movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3880
    add   eax,ecx                ; add error/8 to (x+1;y+1)
3881
    jge   @f                     ; check_overflow
3882
    xor   eax,eax
3883
    jmp   .ok4
3884
  @@:
3885
    cmp   eax,255
3886
    jle   .ok4
3887
    or    al,255
3888
  .ok4:
3889
    mov   [edi+edx+3],al         ; putpixel
3890
 
3891
 
3892
    movzx eax,byte[edi+edx+edx]    ; pixel (x;y+2)
3893
    add   eax,ecx                ; add error/8 to (x;y+2)
3894
    jge   @f                     ; check_overflow
3895
    xor   eax,eax
3896
    jmp   .ok5
3897
  @@:
3898
    cmp   eax,255
3899
    jle   .ok5
3900
    or    al,255
3901
  .ok5:
3902
    mov   [edi+edx+edx],al         ; putpixel
3903
 
3904
  .next:
3905
    inc   edi
3906
    dec   esi
3907
    jnz   newp_4
3908
    ret
3909
 
3910
 
2748 IgorA 3911
;*** функции для работы с воксельной графикой ***
3912
 
3913
 
3914
 
3915
;создание воксельных кистей
3916
align 4
3917
proc vox_brush_create uses eax ebx ecx edi, h_br:dword, buf_z:dword
3918
	mov edi,[h_br]
3919
	movzx ecx,byte[edi+3]
3920
	add edi,4
3921
 
3922
	; *** создание единичной кисти ***
3923
	mov eax,[buf_z]
3924
	mov buf2d_data,eax
3925
	movzx eax,byte[edi-4] ;ширина единичной кисти
3926
	mov buf2d_w,eax ;ширина буфера
3927
	movzx eax,byte[edi-4+1] ;высота единичной кисти
3928
	mov buf2d_h,eax ;высота буфера
3929
	mov buf2d_size_lt,0 ;отступ слева и справа для буфера
3930
	mov buf2d_color,0 ;цвет фона буфера
3931
	mov buf2d_bits,32 ;количество бит в 1-й точке изображения
3932
 
3933
	; *** создание следующих кистей ***
3934
	cmp ecx,1
3935
	jl .end_creat
3936
	movzx ebx,byte[edi-4+2] ;высота основания единичной кисти
3937
	shr ebx,1
3938
	cld
3939
	@@:
3940
		mov eax,edi
3941
		add edi,BUF_STRUCT_SIZE
3942
		stdcall vox_create_next_brush, eax, edi, ebx
3943
		shl ebx,1
3944
		loop @b
3945
	.end_creat:
3946
	ret
3947
endp
3948
 
3949
;удаление воксельных кистей
3950
align 4
3951
proc vox_brush_delete uses ecx edi, h_br:dword
3952
	mov edi,[h_br]
3953
	movzx ecx,byte[edi+3]
3954
	add edi,4
3955
 
3956
	; *** удаление кистей ***
3957
	cmp ecx,1
3958
	jl .end_delete
3959
	cld
3960
	@@:
3961
		add edi,BUF_STRUCT_SIZE
3962
		stdcall buf_delete, edi
3963
		loop @b
3964
	.end_delete:
3965
	ret
3966
endp
3967
 
3968
;функция для создания вокселя следующего порядка
3969
; buf_v1 - буфер с исходным вокселем
3970
; buf_v2 - буфер с увеличеным вокселем
3971
; h - высота основания исходного вокселя : 2
3972
align 4
3973
proc vox_create_next_brush uses eax ebx ecx edx edi, buf_v1:dword, buf_v2:dword, h:dword
3974
	mov edi,[buf_v1]
3975
	mov ebx,buf2d_h
3976
	mov ecx,buf2d_w
3977
	mov edi,[buf_v2]
3978
	mov buf2d_h,ebx
3979
	shl buf2d_h,1
3980
	mov buf2d_w,ecx
3981
	shl buf2d_w,1
3982
	mov buf2d_color,0
3983
	mov buf2d_bits,32
3984
 
3985
	stdcall buf_create, [buf_v2] ;создание буфера глубины
3986
	shr ecx,1
3987
	mov edx,[h]
3988
	shl edx,1
3989
	sub ebx,edx
3990
	;ecx - ширина исходного вокселя : 2
3991
	;ebx - высота исходного вокселя (без основания)
3992
	;edx - высота основания исходного вокселя
3993
	mov eax,[h]
2975 IgorA 3994
	cmp eax,0
3995
	je @f
3996
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,0
3997
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,0
2748 IgorA 3998
 
2975 IgorA 3999
		stdcall vox_add, [buf_v2], [buf_v1], 0,eax,eax
4000
		push eax ;stdcall ...
4001
		add eax,ebx
4002
		stdcall vox_add, [buf_v2], [buf_v1], 0,eax ;,...
4003
		sub eax,ebx
4004
		shl ecx,1
2748 IgorA 4005
 
2975 IgorA 4006
		;ecx - ширина исходного вокселя
4007
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax,eax
4008
		push eax ;stdcall ...,[h]
4009
		add eax,ebx
4010
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax;,[h]
4011
		;sub eax,ebx
4012
		shr ecx,1
2748 IgorA 4013
 
2975 IgorA 4014
		;ecx - ширина исходного вокселя : 2
4015
		stdcall vox_add, [buf_v2], [buf_v1], ecx,edx,edx
4016
		add ebx,edx
4017
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,edx
4018
 
4019
		jmp .end_0
4020
	@@:
4021
		;если h = 0, тогда получаем кисть на 2 грани
4022
		;в таком случае для получения глубины берем ширину / 2
4023
		mov eax,ecx
4024
		;2 левых вокселя
4025
		stdcall vox_add, [buf_v2], [buf_v1], 0,0,eax
4026
		stdcall vox_add, [buf_v2], [buf_v1], 0,ebx,eax
4027
		shl eax,1
4028
		;2 центральных передних вокселя (задние центральные не выводим)
4029
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
4030
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax
4031
		shr eax,1
4032
		shl ecx,1
4033
		;2 правых вокселя
4034
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
4035
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax
4036
 
4037
	.end_0:
4038
 
4039
 
2748 IgorA 4040
	ret
4041
endp
4042
 
4043
;
4044
align 4
2758 IgorA 4045
proc vox_add, buf_v1:dword, buf_v2:dword, coord_x:dword, coord_y:dword, coord_z:dword
2748 IgorA 4046
pushad
2759 IgorA 4047
	mov ebx,[coord_x]
4048
	mov eax,[coord_y]
2748 IgorA 4049
	mov edi,[buf_v2]
4050
	mov ecx,buf2d_h
4051
	mov esi,buf2d_w
4052
	imul ecx,esi
2759 IgorA 4053
	add esi,ebx
2748 IgorA 4054
	mov edx,buf2d_data
4055
	cld
4056
	;ecx - count pixels in voxel
4057
	;edx - указатель на данные в воксельном буфере
4058
	;edi - указатель на воксельный буфер
4059
	;esi - width voxel buffer add coord x
4060
	.cycle:
4061
		cmp dword[edx],0
4062
		je @f
4063
			;проверяем буфер глубины
2759 IgorA 4064
			push eax ecx edi esi
2748 IgorA 4065
			mov ecx,eax
2759 IgorA 4066
			mov edi,[buf_v1]
4067
			call get_pixel_32 ;stdcall buf_get_pixel, [buf_v1],ebx,ecx
2748 IgorA 4068
			mov esi,[edx]
4069
			add esi,[coord_z]
4070
			cmp eax,esi
4071
			jge .end_draw
2759 IgorA 4072
			stdcall buf_set_pixel, [buf_v1],ebx,ecx,esi ;esi = new coord z
2748 IgorA 4073
			.end_draw:
2759 IgorA 4074
			pop esi edi ecx eax
2748 IgorA 4075
		@@:
4076
		add edx,4
2759 IgorA 4077
		inc ebx
4078
		cmp ebx,esi
2748 IgorA 4079
		jl @f
2759 IgorA 4080
			inc eax
4081
			sub ebx,buf2d_w
2748 IgorA 4082
		@@:
4083
		loop .cycle
4084
popad
4085
	ret
4086
endp
4087
 
2758 IgorA 4088
;description:
4089
; возврашает ширину воксельного изображения с 3-мя гранями
4090
; принимает указатель на кисть и масштаб
4091
align 4
4092
proc buf_vox_obj_get_img_w_3g uses ecx, h_br:dword,k_scale:dword
4093
	mov ecx,[h_br]
4094
 
4095
	movzx eax,byte[ecx]
4096
	cmp dword[k_scale],1
4097
	jl .end_c0
4098
		mov ecx,[k_scale]
4099
		shl eax,cl
4100
	.end_c0:
4101
	ret
4102
endp
4103
 
4104
;description:
4105
; возврашает высоту воксельного изображения с 3-мя гранями
4106
; принимает указатель на кисть и масштаб
4107
align 4
4108
proc buf_vox_obj_get_img_h_3g uses ecx, h_br:dword,k_scale:dword
4109
	mov ecx,[h_br]
4110
 
4111
	movzx eax,byte[ecx+1]
4112
	cmp dword[k_scale],1
4113
	jl .end_c0
4114
		mov ecx,[k_scale]
4115
		shl eax,cl
4116
	.end_c0:
4117
	ret
4118
endp
4119
 
4120
;description:
2815 IgorA 4121
; функция рисующая воксельный объект (видна 1 грань)
2758 IgorA 4122
;input:
4123
; buf_i - буфер в котором рисуется (24 бита)
4124
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2815 IgorA 4125
align 4
4126
proc buf_vox_obj_draw_1g, buf_i:dword, buf_z:dword, v_obj:dword, coord_x:dword,\
4127
coord_y:dword, k_scale:dword
4128
	cmp [k_scale],0
4129
	jl .end_f
4130
pushad
4131
	mov edi,[buf_i]
4132
	cmp buf2d_bits,24
4133
	jne .error1
4134
	mov edi,[buf_z]
4135
	cmp buf2d_bits,32
4136
	jne .error2
4137
 
4138
	mov ecx,[k_scale]
4139
	mov ebx,[coord_x]
4140
	mov edx,[coord_y]
4141
	mov edi,[v_obj]
4142
	add edi,vox_offs_data
4143
	xor esi,esi
4144
	stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
4145
 
4146
	jmp .end_0
4147
	.error1:
4148
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n24b
4149
		jmp .end_0
4150
	.error2:
4151
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n32b
4152
	.end_0:
4153
popad
4154
	.end_f:
4155
	ret
4156
endp
4157
 
4158
;input:
4159
; ebx - coord_x
4160
; edx - coord_y
4161
; esi - coord_z
4162
; ecx - уровень текушего узла
4163
; edi - указатель на данные воксельного объекта
4164
align 4
4165
proc draw_sub_vox_obj_1g, buf_i:dword, buf_z:dword, v_obj:dword
4166
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4167
	je .sub_trees
4168
 
4169
		;прорисовка рамки если размер узла = 1
4170
		cmp ecx,0
4171
		jne @f
4172
			;проверка глубины esi
4173
			stdcall buf_get_pixel, [buf_z], ebx,edx, esi
4174
			cmp eax,esi
4175
			jge @f
4176
				push ecx
4177
				mov ecx,dword[edi]
4178
				and ecx,0xffffff
4179
				stdcall buf_set_pixel, [buf_i], ebx,edx, ecx
4180
				stdcall buf_set_pixel, [buf_z], ebx,edx, esi
4181
				pop ecx
4182
		@@:
4183
 
4184
		;рекурсивный перебор поддеревьев
4185
		push edx
4186
		;вход внутрь узла
4187
		dec ecx
4188
 
4189
		mov eax,1
4190
		cmp ecx,1
4191
		jl @f
4192
			shl eax,cl
4193
		@@:
4194
 
4195
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4196
 
4197
		mov ah,byte[edi+3]
4198
		add edi,4
4199
		mov al,8
4200
		.cycle:
4201
			bt ax,8 ;тестируем только ah
4202
			jnc .c_next
4203
				push eax ebx edx esi
4204
				stdcall vox_corect_coords_pl, [v_obj],1
4205
				stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
4206
				pop esi edx ebx eax
4207
			.c_next:
4208
			shr ah,1
4209
			dec al
4210
			jnz .cycle
4211
		;выход из узла
4212
		inc ecx
4213
		pop edx
4214
		jmp .end_f
4215
	.sub_trees:
4216
		cmp ecx,0
4217
		jl .end_0 ;не рисуем очень маленькие воксели
4218
 
4219
			;рисуем узел
4220
			mov eax,[edi]
4221
			and eax,0xffffff
4222
 
4223
			cmp ecx,1
4224
			jl @f
4225
				;квадрат больше текущего масштаба
4226
				stdcall vox_draw_square_1g, [buf_i],[buf_z],eax
4227
				jmp .end_0
4228
			@@:
4229
				;квадрат текущего масштаба
4230
				push ecx
4231
				mov ecx,eax
4232
				stdcall buf_get_pixel, [buf_z], ebx,edx
4233
				cmp eax,esi
4234
				jge .end_1
4235
				stdcall buf_set_pixel, [buf_i], ebx,edx,ecx
4236
				stdcall buf_set_pixel, [buf_z], ebx,edx,esi
4237
				.end_1:
4238
				pop ecx
4239
		.end_0:
4240
		add edi,4
4241
	.end_f:
4242
	ret
4243
endp
4244
 
4245
;output:
4246
; eax - разрушается
4247
align 4
4248
proc vox_draw_square_1g uses ecx edx edi, buf_i:dword, buf_z:dword, color:dword
4249
locals
4250
	img_size dd ?
4251
	coord_y dd ?
4252
endl
4253
	mov edi,[buf_z]
4254
	xor eax,eax
4255
	inc eax
4256
	shl eax,cl
4257
	mov [img_size],eax
4258
	mov [coord_y],eax
4259
	.cycle_0:
4260
	push ebx
4261
	mov ecx,[img_size]
4262
	cld
4263
	.cycle_1:
4264
		push ecx
4265
		mov ecx,edx
4266
		call get_pixel_32
4267
		pop ecx
4268
		cmp eax,esi
4269
		jge @f
4270
			stdcall buf_set_pixel, [buf_i], ebx,edx, [color]
4271
			stdcall buf_set_pixel, edi, ebx,edx, esi
4272
		@@:
4273
		inc ebx
4274
	loop .cycle_1
4275
	pop ebx
4276
	inc edx
4277
	dec dword[coord_y]
4278
	jnz .cycle_0
4279
	ret
4280
endp
4281
 
4282
;description:
4283
; функция рисующая воксельный объект (видно 3 грани)
4284
;input:
4285
; buf_i - буфер в котором рисуется (24 бита)
4286
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2758 IgorA 4287
; h_br - кисть с изображениями вокселей (32 бита)
4288
; v_obj - воксельный объект
4289
; k_scale - коэф. для масштабирования изображения
4290
align 4
4291
proc buf_vox_obj_draw_3g, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
4292
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword
4293
pushad
4294
	mov edi,[v_obj]
4295
	mov ecx,[k_scale]
4296
	mov ebx,[coord_x]
4297
	mov edx,[coord_y]
4298
	add edi,vox_offs_data
4299
	mov esi,[coord_z]
4300
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4301
popad
4302
	ret
4303
endp
4304
 
4305
;description:
4306
; функция рисующая часть воксельного объекта
4307
;input:
4308
; buf_i - буфер в котором рисуется (24 бита)
4309
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
4310
; h_br - кисть с изображениями вокселей (32 бита)
4311
; v_obj - воксельный объект
4312
; k_scale - коэф. для масштабирования изображения
4313
align 4
4314
proc buf_vox_obj_draw_3g_scaled, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
4315
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword,\
4316
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword,b_color:dword
4317
pushad
4318
locals
4319
	p_node dd 0 ;родительский узел
4320
endl
4321
	mov edi,[v_obj]
4322
	add edi,vox_offs_data
4323
 
4324
	mov ecx,[k_scale]
4325
	mov ebx,[coord_x]
4326
 
4327
	;тестовая рамка
4328
	mov eax,[h_br]
4329
 
4330
	movzx edx,byte[eax]
4331
	movzx esi,byte[eax+1]
4332
	cmp ecx,1
4333
	jl .end_c0
4334
		shl edx,cl
4335
		shl esi,cl
4336
	.end_c0:
4337
	;stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
4338
 
4339
	;вертикальная полоса
4340
	add ebx,edx
4341
	shr edx,cl
4342
	stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
4343
	mov ecx,[s_k_scale]
4344
	shr esi,cl
4345
	xor eax,eax
4346
	inc eax
4347
	shl eax,cl
4348
	dec eax
4349
	sub eax,[s_c_z] ;значения по оси z возрастают с низу вверх
4350
	imul eax,esi
4351
	add eax,[coord_y]
4352
	stdcall buf_filled_rect_by_size, [buf_i], ebx,eax,edx,esi, [b_color]
4353
	mov ebx,[coord_y]
4354
	shl esi,cl
4355
	add ebx,esi
4356
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
4357
	shr eax,1
4358
	mov esi,[h_br]
4359
	movzx esi,byte[esi+1]
4360
	;ползунок
4361
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,eax,esi, [s_c_x], [s_k_scale], [b_color]
4362
	mov edx,[coord_x]
4363
	add edx,eax
4364
	;ползунок
4365
	stdcall draw_polz_hor, [buf_i], edx,ebx,eax,esi, [s_c_y], [s_k_scale], [b_color]
4366
;---
4367
 
4368
	mov esi,[s_k_scale]
4369
	cmp esi,1
4370
	jl .end_2
4371
 
4372
	; *** (1) ***
4373
	.found:
4374
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
4375
	movzx bx,byte[edi+3]
4376
	mov [p_node],edi
4377
	add edi,4
4378
	cmp eax,0
4379
	je .end_1
4380
	mov ecx,eax
4381
	cld
4382
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
4383
		bt bx,0 ;проверяем есть ли дочерние узлы
4384
		jnc .end_0
4385
			xor eax,eax
4386
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
4387
		.end_0:
4388
		shr bx,1
4389
		loop @b
4390
	.end_1:
4391
	bt bx,0
4392
	jnc .end_2 ;если поддерева не существует
4393
	dec esi
4394
	cmp esi,0
4395
	jg .found
4396
 
4397
	; *** (2) ***
4398
	;рисование части объекта
4399
	mov ecx,[k_scale]
4400
	mov ebx,[coord_x]
4401
	mov edx,[coord_y]
4402
	mov esi,[coord_z]
4403
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4404
	.end_2:
4405
 
4406
popad
4407
	ret
4408
endp
4409
 
4410
;input:
4411
; h_br - кисть с изображениями вокселей (32 бита)
4412
; ebx - coord_x
4413
; edx - coord_y
4414
; esi - coord_z
4415
; ecx - уровень текушего узла
4416
; edi - указатель на данные воксельного объекта
4417
align 4
4418
proc vox_go_in_node, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword
4419
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4420
	je .sub_trees
4421
		;рекурсивный перебор поддеревьев
4422
		push eax edx
4423
 
4424
		;прорисовка рамки если размер узла = 1
4425
		cmp ecx,0
4426
		jne .end_2
4427
			push eax
4428
				stdcall vox_get_sub_brush,[h_br],0 ;определяем кисть для рисования
4429
				cmp eax,0 ;если кисть не найдена
4430
				je @f
4431
					stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
4432
				@@:
4433
			pop eax
4434
		.end_2:
4435
 
4436
		;вход внутрь узла
4437
		dec ecx
4438
;---
4439
		push ebx
4440
			;mov eax,(h-h_osn/2)
4441
			mov ebx,[h_br]
4442
			movzx eax,byte[ebx+1]
2975 IgorA 4443
			cmp byte[ebx+2],0
4444
			je @f
4445
				;если кисть с 3-мя гранями
4446
				movzx ebx,byte[ebx+2]
4447
				shr ebx,1
4448
				sub eax,ebx
4449
				jmp .end_0
4450
			@@:
4451
				;если кисть с 2-мя гранями
4452
				movzx ebx,byte[ebx]
4453
				shr ebx,1
4454
			.end_0:
2758 IgorA 4455
		cmp ecx,1
2975 IgorA 4456
		jl @f
2758 IgorA 4457
			shl eax,cl
4458
			shl ebx,cl
2975 IgorA 4459
		@@:
2758 IgorA 4460
		add esi,ebx
4461
		pop ebx
4462
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4463
;---
4464
		mov ah,byte[edi+3]
4465
		add edi,4
4466
		mov al,8
4467
		.cycle:
4468
			bt ax,8 ;тестируем только ah
4469
			jnc .c_next
4470
				push ebx edx esi
4471
				stdcall vox_corect_coords, [h_br], [v_obj]
4472
				stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4473
				pop esi edx ebx
4474
			.c_next:
4475
			shr ah,1
4476
			dec al
4477
			jnz .cycle
4478
 
4479
		;выход из узла
4480
		inc ecx
4481
		pop edx eax
4482
 
4483
		jmp .end_f
4484
	.sub_trees:
4485
		;рисуем узел
4486
		push eax
4487
			stdcall vox_get_sub_brush,[h_br],ecx ;определяем кисть для рисования
4488
			cmp eax,0 ;если кисть не найдена
4489
			je @f
4490
				stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
4491
			@@:
4492
		pop eax
4493
 
4494
		add edi,4
4495
	.end_f:
4496
	ret
4497
endp
4498
 
4499
;description:
4500
; функция рисующая одиночный воксел
4501
;input:
4502
; buf_i - буфер в котором рисуется (24 бита)
4503
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
4504
; buf_v - буфер с изображением вокселя (32 бита)
4505
; v_color - цвет
4506
align 4
4507
proc draw_vox, buf_i:dword, buf_z:dword, buf_v:dword,\
4508
coord_x:dword, coord_y:dword, coord_z:dword, v_color:dword
4509
pushad
4510
	mov eax,[coord_x]
4511
	mov ebx,[coord_y]
4512
	mov edi,[buf_v]
4513
	mov ecx,buf2d_h
4514
	mov esi,buf2d_w
4515
	imul ecx,esi
4516
	add esi,eax
4517
	mov edx,buf2d_data
4518
	cld
4519
	;ecx - count pixels in voxel
4520
	;edx - указатель на данные в воксельном буфере
4521
	;edi - указатель на воксельный буфер
4522
	;esi - width voxel buffer add coord x
4523
	.cycle:
4524
		cmp dword[edx],0
4525
		je @f
4526
			;проверяем буфер глубины
4527
			push eax
4528
			stdcall buf_get_pixel, [buf_z],eax,ebx
4529
			sub eax,[coord_z]
4530
			cmp eax,[edx]
4531
			jl .dr_pixel
4532
				pop eax
4533
				jmp @f
4534
			.dr_pixel:
4535
				;рисуем точку
4536
				pop eax
4537
				stdcall buf_set_pixel, [buf_i],eax,ebx,[v_color]
4538
				push ecx
4539
				mov ecx,[coord_z]
4540
				add ecx,[edx]
4541
				stdcall buf_set_pixel, [buf_z],eax,ebx,ecx
4542
				pop ecx
4543
		@@:
4544
		add edx,4
4545
		inc eax
4546
		cmp eax,esi
4547
		jl @f
4548
			inc ebx
4549
			sub eax,buf2d_w
4550
		@@:
4551
		loop .cycle
4552
popad
4553
	ret
4554
endp
4555
 
4556
;description:
4557
;функция для коректировки координат
4558
;направления осей координат в вокселе:
4559
;*z
4560
;|
4561
;+
4562
;  * y
4563
; /
4564
;+
4565
; \
4566
;  * x
4567
;input:
4568
;  al - номер узла в дереве (от 1 до 8)
4569
; ebx - координата x
4570
; edx - координата y
4571
; esi - координата z
4572
; ecx - уровень текушего узла
4573
;output:
4574
; ebx - новая координата x
4575
; edx - новая координата y
4576
; esi - новая координата z
4577
align 4
4578
proc vox_corect_coords, h_br:dword, v_obj:dword
4579
locals
4580
	osn_w_2 dd ? ;ширина основания единичного вокселя : 2
4581
	vox_h dd ? ;высота единичного вокселя
4582
endl
4583
	cmp ecx,0
4584
	jl .end_f ;для ускорения отрисовки
4585
 
4586
	push eax edi
4587
	and eax,15 ;выделяем номер узла в дереве
4588
	mov edi,[v_obj]
4589
	add edi,vox_offs_tree_table
4590
	add edi,8
4591
	sub edi,eax
4592
 
4593
	push ebx ecx
4594
		mov ebx,[h_br]
4595
 
4596
		movzx ecx,byte[ebx]
4597
		shr ecx,1
4598
		mov dword[osn_w_2],ecx
4599
 
4600
		movzx ecx,byte[ebx+2]
4601
		movzx ebx,byte[ebx+1]
4602
		sub ebx,ecx
4603
		mov dword[vox_h],ebx
4604
		shr ecx,1
4605
		mov eax,ecx ;eax - высота основания единичного вокселя : 2
4606
	pop ecx ebx
4607
 
4608
	cmp ecx,1
2975 IgorA 4609
	jl @f ;во избежание зацикливания
2758 IgorA 4610
		shl eax,cl
4611
		shl dword[osn_w_2],cl
4612
		shl dword[vox_h],cl
2975 IgorA 4613
	@@:
2758 IgorA 4614
 
4615
;	add esi,eax ;меняем глубину для буфера z (компенсация для координаты y)
4616
	bt word[edi],0 ;test voxel coord x
4617
	jnc @f
4618
		add ebx,[osn_w_2]
2975 IgorA 4619
		cmp eax,0
4620
		jne .end_0
4621
			add esi,[osn_w_2] ;меняем глубину для буфера z
4622
			jmp @f
4623
		.end_0:
2758 IgorA 4624
		add edx,eax
4625
		add esi,eax ;меняем глубину для буфера z
4626
	@@:
4627
	bt word[edi],1 ;test voxel coord y
4628
	jnc @f
4629
		add ebx,[osn_w_2]
2975 IgorA 4630
		cmp eax,0
4631
		jne .end_1
4632
			sub esi,[osn_w_2] ;меняем глубину для буфера z
4633
			jmp @f
4634
		.end_1:
2758 IgorA 4635
		sub edx,eax
4636
		sub esi,eax ;меняем глубину для буфера z
4637
	@@:
4638
	bt word[edi],2 ;test voxel coord z
4639
	jnc @f
4640
		sub edx,[vox_h]
4641
	@@:
4642
	pop edi eax
4643
	.end_f:
4644
	ret
4645
endp
4646
 
4647
;извлекаем из h_br указатель на буфер с изображением вокселя, указанного порядка n
4648
align 4
4649
proc vox_get_sub_brush uses ebx ecx, h_br:dword, n:dword
4650
	xor eax,eax
4651
	mov ebx,[n]
4652
	cmp ebx,0
4653
	jl @f
4654
	mov ecx,[h_br]
4655
	cmp bl,byte[ecx+3]
4656
	jg @f
4657
		add ecx,4
4658
		imul ebx,BUF_STRUCT_SIZE
4659
		mov eax,ebx
4660
		add eax,ecx
4661
	@@:
4662
	ret
4663
endp
4664
 
4665
;description:
4666
; функция рисующая срез воксельного обьекта
4667
;input:
4668
; v_size - размер квадрата с вокселем
4669
; k_scale - степень детализации изображения
4670
; n_plane - номер плоскости сечния (в пределах от 0 до 2^k_scale - 1)
4671
; b_color - цвет границы
4672
align 4
4673
proc buf_vox_obj_draw_pl, buf_i:dword, v_obj:dword, coord_x:dword,\
4674
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword
4675
	cmp [k_scale],0
4676
	jl .end_f
4677
pushad
4678
	mov eax,[v_size]
4679
	mov ecx,[k_scale]
4680
	mov ebx,eax
4681
	cmp ecx,1
4682
	jl @f
4683
		shl ebx,cl
4684
	@@:
4685
	;ebx - полный размер изображения
4686
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
4687
	mov edx,ebx
4688
	add ebx,[coord_y]
4689
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
4690
 
4691
	;рисование точек для сетки
4692
	push ecx
4693
	mov edi,1
4694
	cmp ecx,1
4695
	jl @f
4696
		shl edi,cl
4697
	@@:
4698
	dec edi
4699
	cmp edi,1
4700
	jl .end_0
4701
	mov ecx,edi
4702
	imul ecx,edi
4703
	mov ebx,[coord_x]
4704
	mov edx,[coord_y]
4705
	add edx,eax
4706
	xor esi,esi
4707
	cld
4708
	@@:
4709
		add ebx,eax
4710
		inc esi
4711
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
4712
		cmp esi,edi
4713
		jl .end_1
4714
			;переход точек на новую строку
4715
			xor esi,esi
4716
			mov ebx,[coord_x]
4717
			add edx,eax
4718
		.end_1:
4719
		loop @b
4720
	.end_0:
4721
	pop ecx
4722
 
4723
	;eax - размер одного квадрата
2815 IgorA 4724
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 4725
	mov ebx,[coord_x]
4726
	mov edx,[coord_y]
4727
	mov edi,[v_obj]
4728
	add edi,vox_offs_data
4729
	xor esi,esi
4730
	push eax
2815 IgorA 4731
	mov eax,1
4732
	shl eax,cl
4733
	dec eax
4734
	sub eax,[n_plane]
4735
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],eax
2758 IgorA 4736
popad
4737
	.end_f:
4738
	ret
4739
endp
4740
 
4741
;description:
4742
; функция рисующая срез части воксельного обьекта
4743
;input:
4744
; s_c_x, s_c_y, s_c_z, s_k_scale - параметры определяющие часть воксельного объекта, которая будет рисоваться
4745
align 4
4746
proc buf_vox_obj_draw_pl_scaled, buf_i:dword, v_obj:dword, coord_x:dword,\
4747
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword,\
4748
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword
4749
	cmp [k_scale],0
4750
	jl .end_f
4751
pushad
4752
locals
4753
	p_node dd 0 ;родительский узел
4754
endl
4755
	mov eax,[v_size]
4756
	mov ecx,[k_scale]
4757
	mov ebx,eax
4758
	cmp ecx,1
4759
	jl @f
4760
		shl ebx,cl
4761
	@@:
4762
	;ebx - полный размер изображения
4763
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
4764
	mov edx,ebx
4765
	add ebx,[coord_y]
4766
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
4767
 
4768
	;рисование точек для сетки
4769
	push ecx
4770
	mov edi,1
4771
	cmp ecx,1
4772
	jl @f
4773
		shl edi,cl
4774
	@@:
4775
	dec edi
4776
	cmp edi,1
4777
	jl .end_3
4778
	mov ecx,edi
4779
	imul ecx,edi
4780
	mov ebx,[coord_x]
4781
	mov edx,[coord_y]
4782
	add edx,eax
4783
	xor esi,esi
4784
	cld
4785
	@@:
4786
		add ebx,eax
4787
		inc esi
4788
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
4789
		cmp esi,edi
4790
		jl .end_4
4791
			;переход точек на новую строку
4792
			xor esi,esi
4793
			mov ebx,[coord_x]
4794
			add edx,eax
4795
		.end_4:
4796
		loop @b
4797
	.end_3:
4798
	pop ecx
4799
 
4800
	mov esi,[s_k_scale]
4801
	cmp esi,1
4802
	jl .end_2
4803
	mov edi,[v_obj]
4804
	add edi,vox_offs_data
4805
 
4806
	; *** (1) ***
4807
	.found:
4808
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
4809
	movzx bx,byte[edi+3]
4810
	mov [p_node],edi
4811
	add edi,4
4812
	cmp eax,0
4813
	je .end_1
4814
	mov ecx,eax
4815
	cld
4816
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
4817
		bt bx,0 ;проверяем есть ли дочерние узлы
4818
		jnc .end_0
4819
			xor eax,eax
4820
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
4821
		.end_0:
4822
		shr bx,1
4823
		loop @b
4824
	.end_1:
4825
	bt bx,0
4826
	jnc .end_2 ;если поддерева не существует
4827
	dec esi
4828
	cmp esi,0
4829
	jg .found
4830
 
4831
	mov eax,[v_size]
4832
	;eax - размер одного квадрата
2815 IgorA 4833
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 4834
	mov ecx,[k_scale]
4835
	mov ebx,[coord_x]
4836
	mov edx,[coord_y]
4837
	xor esi,esi
4838
	push eax
2815 IgorA 4839
	mov eax,1
4840
	shl eax,cl
4841
	dec eax
4842
	sub eax,[n_plane]
2758 IgorA 4843
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj], eax
4844
 
4845
	.end_2:
4846
popad
4847
	.end_f:
4848
	ret
4849
endp
4850
 
4851
;description:
4852
; определение позиции узла в дереве (от 0 до 7)
4853
align 4
4854
proc vox_obj_get_node_position uses ebx ecx edi, v_obj:dword,\
4855
coord_x:dword,coord_y:dword,coord_z:dword,k_scale:dword
4856
	mov ecx,[k_scale]
4857
	dec ecx
4858
	mov eax,[coord_x]
4859
	mov ebx,[coord_y]
4860
	mov edi,[coord_z]
4861
	cmp ecx,1
4862
	jl .end_0
4863
		shr eax,cl
4864
		shr ebx,cl
4865
		shr edi,cl
4866
	.end_0:
4867
	and eax,1
4868
	bt ebx,0
4869
	jnc @f
4870
		bts eax,1
4871
	@@:
4872
	bt edi,0
4873
	jnc @f
4874
		bts eax,2
4875
	@@:
4876
 
4877
	mov edi,[v_obj]
4878
	add edi,vox_offs_tree_table
4879
	@@:
4880
		cmp al,byte[edi]
4881
		je @f
4882
		inc edi
4883
		jmp @b
4884
	@@:
4885
	sub edi,[v_obj]
4886
	sub edi,vox_offs_tree_table
4887
	mov eax,edi
4888
 
4889
	ret
4890
endp
4891
 
4892
;input:
4893
; edi - указатель на данные воксельного объекта
4894
;output:
4895
; eax - eax + число узлов в данных вокс. объекта
4896
; edi - указатель на смещенные данные вокс. объекта
4897
align 4
4898
proc vox_obj_rec0
4899
	inc eax
4900
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4901
	je .sub_trees
4902
 
4903
		;рекурсивный перебор поддеревьев
4904
		push ebx ecx
4905
		mov bh,byte[edi+3]
4906
		add edi,4
4907
		mov bl,8
4908
		.cycle:
4909
			bt bx,8 ;тестируем только bh
4910
			jnc .c_next
4911
				stdcall vox_obj_rec0
4912
			.c_next:
4913
			shr bh,1
4914
			dec bl
4915
			jnz .cycle
4916
		pop ecx ebx
4917
 
4918
		jmp .end_f
4919
	.sub_trees:
4920
		add edi,4
4921
	.end_f:
4922
	ret
4923
endp
4924
 
4925
;description:
4926
; функция рисующая горизонтальную полосу с ползунком
4927
align 4
4928
proc draw_polz_hor uses eax ebx ecx, buf:dword, coord_x:dword, coord_y:dword,\
4929
size_x:dword, size_y:dword, pos:dword, k_scale:dword, color:dword
4930
	mov ebx,[size_x]
4931
	stdcall buf_rect_by_size, [buf], [coord_x],[coord_y],ebx,[size_y], [color]
4932
	mov ecx,[k_scale]
4933
	shr ebx,cl
4934
	mov eax,[pos]
4935
	imul eax,ebx
4936
	add eax,[coord_x]
4937
	stdcall buf_filled_rect_by_size, [buf], eax,[coord_y],ebx,[size_y], [color]
4938
	ret
4939
endp
4940
 
4941
;input:
4942
; ebx - coord_x
4943
; edx - coord_y
4944
; esi - coord_z
4945
; ecx - уровень текушего узла
4946
; edi - указатель на данные воксельного объекта
4947
align 4
4948
proc draw_sub_vox_obj_pl, buf_i:dword, v_obj:dword, clip_z:dword,\
4949
v_size:dword
4950
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4951
	je .sub_trees
4952
 
4953
		;прорисовка рамки если размер узла = 1
4954
		cmp ecx,0
4955
		jne @f
2815 IgorA 4956
			;проверка глубины esi
4957
			;clip_z=n_plane
4958
			stdcall vox_is_clip, [clip_z];,[v_size]
4959
			cmp eax,0
4960
			je @f
4961
				push ecx
4962
				mov ecx,dword[edi]
4963
				and ecx,0xffffff
4964
				stdcall buf_rect_by_size, [buf_i], ebx,edx, [v_size],[v_size],ecx
4965
				pop ecx
2758 IgorA 4966
		@@:
4967
 
4968
		;рекурсивный перебор поддеревьев
4969
		push edx
4970
		;вход внутрь узла
4971
		dec ecx
4972
 
4973
		mov eax,[v_size]
4974
		cmp ecx,1
4975
		jl @f
4976
			shl eax,cl
4977
		@@:
2815 IgorA 4978
 
2758 IgorA 4979
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4980
 
4981
		mov ah,byte[edi+3]
4982
		add edi,4
4983
		mov al,8
4984
		.cycle:
4985
			bt ax,8 ;тестируем только ah
4986
			jnc .c_next
4987
				push eax ebx edx esi
4988
				stdcall vox_corect_coords_pl, [v_obj],[v_size]
4989
				stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],[clip_z],[v_size]
4990
				pop esi edx ebx eax
4991
			.c_next:
4992
			shr ah,1
4993
			dec al
4994
			jnz .cycle
4995
		;выход из узла
4996
		inc ecx
4997
		pop edx
4998
		jmp .end_f
4999
	.sub_trees:
5000
		cmp ecx,0
5001
		jl .end_0 ;не рисуем очень маленькие воксели
5002
 
2815 IgorA 5003
			;проверка глубины esi
5004
			;clip_z=n_plane
5005
			stdcall vox_is_clip, [clip_z]
5006
			cmp eax,0
5007
			je .end_0
2758 IgorA 5008
 
2815 IgorA 5009
			;рисуем узел
5010
			mov eax,[edi]
5011
			and eax,0xffffff
5012
			push eax ;цвет узла
2758 IgorA 5013
 
2815 IgorA 5014
			mov eax,[v_size]
5015
			cmp ecx,1
5016
			jl @f
5017
				;квадрат больше текущего масштаба
5018
				shl eax,cl ;размер узла
5019
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
5020
				push ebx edx esi
5021
				mov esi,eax
5022
				inc ebx
5023
				inc edx
5024
				sub esi,2
5025
				mov eax,[buf_i]
5026
				push dword 128
5027
				push dword[eax+16] ;+16 - b_color
5028
				stdcall combine_colors_3,[edi]
5029
				stdcall buf_rect_by_size, [buf_i], ebx,edx, esi,esi,eax
5030
				pop esi edx ebx
5031
				jmp .end_0
5032
			@@:
5033
				;квадрат текущего масштаба
5034
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
2758 IgorA 5035
		.end_0:
5036
		add edi,4
5037
	.end_f:
5038
	ret
5039
endp
5040
 
5041
;description:
5042
; вспомогательная функция для проверки глубины esi
5043
;input:
5044
; ecx - уровень текушего узла
5045
; esi - coord z
2815 IgorA 5046
; clip_z - n_plane
2758 IgorA 5047
;output:
5048
; eax - 0 if no draw, 1 if draw
5049
align 4
2815 IgorA 5050
proc vox_is_clip uses ebx edi, clip_z:dword
2758 IgorA 5051
	xor eax,eax
5052
	mov ebx,[clip_z]
2815 IgorA 5053
	mov edi,1
2758 IgorA 5054
	cmp ecx,1
5055
	jl @f
5056
		shl edi,cl
5057
	@@:
5058
	;edi = 2^ecx
5059
	add edi,esi
2815 IgorA 5060
	cmp edi,ebx ;if (esi+2^ecx <= n_plane) no draw
2758 IgorA 5061
	jle @f
2815 IgorA 5062
	inc ebx
5063
	cmp esi,ebx ;if (esi >= (n_plane+1)) no draw
2758 IgorA 5064
	jge @f
5065
		inc eax
5066
	@@:
5067
	ret
5068
endp
5069
 
5070
;функция для коректировки координат
5071
;направления осей координат в вокселе:
5072
;*z
5073
;|
5074
;+-* x
5075
;input:
5076
;  al - номер узла в дереве (от 1 до 8)
5077
; ebx - координата x
5078
; edx - координата y
5079
; esi - координата z
5080
; ecx - уровень текушего узла
5081
;output:
5082
; ebx - новая координата x
5083
; edx - новая координата y
5084
; esi - новая координата z
5085
align 4
5086
proc vox_corect_coords_pl, v_obj:dword, v_size:dword
5087
	cmp ecx,0
5088
	jl .end_f ;для ускорения отрисовки
5089
 
5090
	push eax edi
5091
	and eax,15 ;выделяем номер узла в дереве
5092
	mov edi,[v_obj]
5093
	add edi,vox_offs_tree_table
5094
	add edi,8
5095
	sub edi,eax
5096
 
2815 IgorA 5097
	mov eax,[v_size]
2758 IgorA 5098
	cmp ecx,1
2815 IgorA 5099
	jl @f
2758 IgorA 5100
		shl eax,cl
5101
	@@:
5102
 
5103
	bt word[edi],0 ;test voxel coord x
5104
	jnc @f
5105
		add ebx,eax
5106
	@@:
5107
	bt word[edi],2 ;test voxel coord z
5108
	jnc @f
5109
		sub edx,eax
5110
	@@:
2815 IgorA 5111
	bt word[edi],1 ;test voxel coord y
5112
	jc @f
5113
		mov eax,1
5114
		cmp ecx,1
5115
		jl .end_0
5116
			shl eax,cl
5117
		.end_0:
5118
		add esi,eax ;меняем глубину для буфера z
5119
	@@:
2758 IgorA 5120
	pop edi eax
5121
	.end_f:
5122
	ret
5123
endp
5124
 
5125
;description:
5126
; функция рисующая тени
5127
;input:
5128
; buf_i - буфер в котором рисуется (24 бита)
5129
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
5130
; h_br - кисть с изображениями вокселей (32 бита)
5131
; k_scale - коэф. для масштабирования изображения
5132
align 4
5133
proc buf_vox_obj_draw_3g_shadows, buf_i:dword, buf_z:dword, h_br:dword, \
5134
coord_x:dword, coord_y:dword, color:dword, k_scale:dword, prop:dword
5135
locals
5136
	correct_z dd 0 ;коректировка для буфера глубины
5137
endl
5138
pushad
5139
	mov eax,[k_scale]
5140
	add eax,[prop]
5141
	mov dword[correct_z],8
5142
	sub [correct_z],eax
5143
	mov ebx,[coord_x]
5144
	;correct_z = 8-k_scale-prop
5145
 
5146
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
5147
	mov edx,eax ;edx - ширина изображения
5148
	stdcall buf_vox_obj_get_img_h_3g, [h_br],[k_scale]
5149
	mov esi,eax
5150
 
5151
	mov edi,[coord_y]
5152
	mov ecx,edx
5153
	add edx,ebx ;ширина + отступ слева
5154
	imul ecx,esi
5155
	cld
5156
	.cycle_0:
5157
		stdcall buf_get_pixel, [buf_z],ebx,edi
5158
		cmp eax,0
5159
		je @f
5160
			stdcall vox_correct_z, [correct_z]
5161
			push eax
5162
			stdcall buf_get_pixel, [buf_i],ebx,edi
5163
			stdcall combine_colors_3,eax,[color] ;,eax
5164
			stdcall buf_set_pixel, [buf_i],ebx,edi,eax
5165
		@@:
5166
		inc ebx
5167
		cmp ebx,edx
5168
		jl @f
5169
			mov ebx,[coord_x]
5170
			inc edi
5171
		@@:
5172
		loop .cycle_0
5173
 
5174
popad
5175
	ret
5176
endp
5177
 
5178
;output:
5179
; eax - scaled coord z
5180
align 4
5181
proc vox_correct_z uses ecx, correct_z:dword
5182
	mov ecx,[correct_z]
5183
	cmp ecx,0
5184
	je .end_f
5185
	jl .end_0
5186
		shl eax,cl
5187
		jmp .end_f
5188
	.end_0:
5189
		neg ecx
5190
		inc ecx
5191
		shr eax,cl
5192
	.end_f:
5193
	ret
5194
endp
5195
 
5196
;output:
5197
; eax - color
5198
align 4
5199
proc combine_colors_3 uses ebx ecx edx edi esi, col_0:dword, col_1:dword, alpha:dword
5200
 
5201
	mov ebx,[col_0]
5202
	mov ecx,[col_1]
5203
	movzx di,byte[alpha] ;pro
5204
	mov si,0x00ff ;---get transparent---
5205
	sub si,di ;256-pro
5206
 
5207
	;---blye---
5208
	movzx ax,bl
5209
	imul ax,si
5210
	movzx dx,cl
5211
	imul dx,di
5212
	add ax,dx
5213
	mov cl,ah
5214
	;---green---
5215
	movzx ax,bh
5216
	imul ax,si
5217
	movzx dx,ch
5218
	imul dx,di
5219
	add ax,dx
5220
	mov ch,ah
5221
	shr ebx,16
5222
	ror ecx,16
5223
	;---red---
5224
	movzx ax,bl
5225
	imul ax,si
5226
	movzx dx,cl
5227
	imul dx,di
5228
	add ax,dx
5229
 
5230
	shl eax,8
5231
	ror ecx,16
5232
	mov ax,cx
5233
	and eax,0xffffff
5234
 
5235
	ret
5236
endp
5237
 
1535 IgorA 5238
txt_err_n8b db 'need buffer 8 bit',13,10,0
5239
txt_err_n24b db 'need buffer 24 bit',13,10,0
2815 IgorA 5240
txt_err_n32b db 'need buffer 32 bit',13,10,0
2358 IgorA 5241
txt_err_n8_24b db 'need buffer 8 or 24 bit',13,10,0
1535 IgorA 5242
 
5243
align 16
5244
EXPORTS:
5245
	dd sz_lib_init, lib_init
5246
	dd sz_buf2d_create, buf_create
5247
	dd sz_buf2d_create_f_img, buf_create_f_img
5248
	dd sz_buf2d_clear, buf_clear
5249
	dd sz_buf2d_draw, buf_draw_buf
5250
	dd sz_buf2d_delete, buf_delete
2136 IgorA 5251
	dd sz_buf2d_resize, buf_resize
2975 IgorA 5252
	dd sz_buf2d_rotate, buf_rotate
1535 IgorA 5253
	dd sz_buf2d_line, buf_line_brs
2230 IgorA 5254
	dd sz_buf2d_line_sm, buf_line_brs_sm
1634 IgorA 5255
	dd sz_buf2d_rect_by_size, buf_rect_by_size
1642 IgorA 5256
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
1535 IgorA 5257
	dd sz_buf2d_circle, buf_circle
5258
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
5259
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
5260
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
5261
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
5262
	dd sz_buf2d_bit_blt, buf_bit_blt
5263
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
5264
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1727 IgorA 5265
	dd sz_buf2d_curve_bezier, buf_curve_bezier
1535 IgorA 5266
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
5267
	dd sz_buf2d_draw_text, buf_draw_text
5268
	dd sz_buf2d_crop_color, buf_crop_color
5269
	dd sz_buf2d_offset_h, buf_offset_h
1684 IgorA 5270
	dd sz_buf2d_flood_fill, buf_flood_fill
1910 IgorA 5271
	dd sz_buf2d_set_pixel, buf_set_pixel
2658 IgorA 5272
	dd sz_buf2d_get_pixel, buf_get_pixel
3040 IgorA 5273
	dd sz_buf2d_flip_v, buf_flip_v
3105 IgorA 5274
	dd sz_buf2d_filter_dither, buf_filter_dither
2748 IgorA 5275
	dd sz_buf2d_vox_brush_create, vox_brush_create
5276
	dd sz_buf2d_vox_brush_delete, vox_brush_delete
2758 IgorA 5277
	dd sz_buf2d_vox_obj_get_img_w_3g, buf_vox_obj_get_img_w_3g
5278
	dd sz_buf2d_vox_obj_get_img_h_3g, buf_vox_obj_get_img_h_3g
2815 IgorA 5279
	dd sz_buf2d_vox_obj_draw_1g, buf_vox_obj_draw_1g
2758 IgorA 5280
	dd sz_buf2d_vox_obj_draw_3g, buf_vox_obj_draw_3g
5281
	dd sz_buf2d_vox_obj_draw_3g_scaled, buf_vox_obj_draw_3g_scaled
5282
	dd sz_buf2d_vox_obj_draw_pl, buf_vox_obj_draw_pl
5283
	dd sz_buf2d_vox_obj_draw_pl_scaled, buf_vox_obj_draw_pl_scaled
5284
	dd sz_buf2d_vox_obj_draw_3g_shadows, buf_vox_obj_draw_3g_shadows
1535 IgorA 5285
	dd 0,0
5286
	sz_lib_init db 'lib_init',0
5287
	sz_buf2d_create db 'buf2d_create',0
5288
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
5289
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
5290
	sz_buf2d_draw db 'buf2d_draw',0
5291
	sz_buf2d_delete db 'buf2d_delete',0
2136 IgorA 5292
	sz_buf2d_resize db 'buf2d_resize',0
2975 IgorA 5293
	sz_buf2d_rotate db 'buf2d_rotate',0
1535 IgorA 5294
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
2230 IgorA 5295
	sz_buf2d_line_sm db 'buf2d_line_sm',0 ;рисование сглаженной линии
1642 IgorA 5296
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;рисование рамки прямоугольника, 2-я координата задана по размеру
5297
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;рисование залитого прямоугольника, 2-я координата задана по размеру
1535 IgorA 5298
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
5299
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
5300
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
5301
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
5302
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
5303
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
5304
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
5305
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1727 IgorA 5306
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
1535 IgorA 5307
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
5308
	sz_buf2d_draw_text db 'buf2d_draw_text',0
5309
	sz_buf2d_crop_color db 'buf2d_crop_color',0
5310
	sz_buf2d_offset_h db 'buf2d_offset_h',0
1684 IgorA 5311
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
1910 IgorA 5312
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
2658 IgorA 5313
	sz_buf2d_get_pixel db 'buf2d_get_pixel',0
3040 IgorA 5314
	sz_buf2d_flip_v db 'buf2d_flip_v',0
3105 IgorA 5315
	sz_buf2d_filter_dither db 'buf2d_filter_dither',0
2748 IgorA 5316
	sz_buf2d_vox_brush_create db 'buf2d_vox_brush_create',0
5317
	sz_buf2d_vox_brush_delete db 'buf2d_vox_brush_delete',0
2758 IgorA 5318
	sz_buf2d_vox_obj_get_img_w_3g db 'buf2d_vox_obj_get_img_w_3g',0
5319
	sz_buf2d_vox_obj_get_img_h_3g db 'buf2d_vox_obj_get_img_h_3g',0
2815 IgorA 5320
	sz_buf2d_vox_obj_draw_1g db 'buf2d_vox_obj_draw_1g',0
2758 IgorA 5321
	sz_buf2d_vox_obj_draw_3g db 'buf2d_vox_obj_draw_3g',0
5322
	sz_buf2d_vox_obj_draw_3g_scaled db 'buf2d_vox_obj_draw_3g_scaled',0
5323
	sz_buf2d_vox_obj_draw_pl db 'buf2d_vox_obj_draw_pl',0
5324
	sz_buf2d_vox_obj_draw_pl_scaled db 'buf2d_vox_obj_draw_pl_scaled',0
5325
	sz_buf2d_vox_obj_draw_3g_shadows db 'buf2d_vox_obj_draw_3g_shadows',0