Subversion Repositories Kolibri OS

Rev

Rev 3138 | Rev 6175 | 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
 
5389 IgorA 1989
align 4
1990
proc buf_flip_h, buf_struc:dword
1991
pushad
1992
	mov edi,[buf_struc]
1993
	cmp buf2d_bits,24
1994
	jne .end_24
1995
		mov esi,buf2d_data
1996
		mov eax,buf2d_w
1997
		mov ecx,eax
1998
		shr ecx,1
1999
		dec eax
2000
		lea eax,[eax+eax*2]
2001
		mov ebx,buf2d_h
2002
		mov edi,esi
2003
		add esi,eax
2004
		add eax,3
2005
		cld
2006
		.cycle_24:
2007
		push ecx edi esi
2008
align 4
2009
		@@:
2010
			;swap word[edi] <-> word[esi]
2011
			mov dx,[edi]
2012
			movsw
2013
			mov [esi-2],dx
2014
			;swap byte[edi] <-> byte[esi]
2015
			mov dl,[edi]
2016
			movsb
2017
			mov [esi-1],dl
2018
			sub esi,6
2019
		loop @b
2020
		pop esi edi ecx
2021
		add edi,eax
2022
		add esi,eax
2023
		dec ebx
2024
		or ebx,ebx
2025
		jnz .cycle_24
2026
		jmp .end_32
2027
	.end_24:
2028
	cmp buf2d_bits,32
2029
	jne .end_32
2030
		mov esi,buf2d_data
2031
		mov eax,buf2d_w
2032
		dec eax
2033
		shl eax,2
2034
		mov ebx,buf2d_h
2035
		mov edi,esi
2036
		add esi,eax
2037
		add eax,4
2038
		cld
2039
		.cycle_32:
2040
		mov ecx,eax
2041
		shr ecx,3
2042
		push edi esi
2043
align 4
2044
		@@:
2045
			;swap dword[edi] <-> dword[esi]
2046
			mov edx,[edi]
2047
			movsd
2048
			mov [esi-4],edx
2049
			sub esi,8
2050
		loop @b
2051
		pop esi edi
2052
		add edi,eax
2053
		add esi,eax
2054
		dec ebx
2055
		or ebx,ebx
2056
		jnz .cycle_32
2057
	.end_32:
2058
popad
2059
	ret
2060
endp
2061
 
3040 IgorA 2062
;отразить по вертикали (верх и низ меняются местами)
2658 IgorA 2063
align 4
3040 IgorA 2064
proc buf_flip_v, buf_struc:dword
2065
locals
5389 IgorA 2066
	line_pix dd ? ;кол. пикселей в линии буфера
2067
	line_2byte dd ? ;кол. байт в линии буфера * 2
3040 IgorA 2068
endl
2069
	pushad
2070
	mov edi,[buf_struc]
5389 IgorA 2071
	cmp buf2d_bits,24
2072
	jne .end_24
2073
		mov edx,buf2d_w
2074
		mov [line_pix],edx
2075
		mov ebx,buf2d_h
2076
		lea edx,[edx+edx*2]
2077
		mov esi,edx
2078
		imul esi,ebx
2079
		sub esi,edx
2080
		add esi,buf2d_data ;указатель на нижнюю линию
2081
		shr ebx,1 ;кол. линейных циклов
2082
		shl edx,1
2083
		mov [line_2byte],edx
2084
		mov edi,buf2d_data
2085
		xchg edi,esi
2086
		cld
2087
		.flip_24:
2088
		cmp ebx,0
2089
		jle .end_32 ;здесь выход из функции (потому .end_24 не подходит)
2090
		mov ecx,[line_pix]
2091
align 4
2092
		@@:
2093
			lodsw
2094
			mov dx,word[edi]
2095
			mov word[esi-2],dx
2096
			stosw
2097
			lodsb
2098
			mov ah,byte[edi]
2099
			mov byte[esi-1],ah
2100
			stosb
2101
			loop @b
2102
		sub edi,[line_2byte]
2103
		dec ebx
2104
		jmp .flip_24
2105
	.end_24:
2106
	cmp buf2d_bits,32
2107
	jne .end_32
2108
		mov edx,buf2d_w
2109
		mov [line_pix],edx
2110
		mov ebx,buf2d_h
2111
		shl edx,2
2112
		mov esi,edx
2113
		imul esi,ebx
2114
		sub esi,edx
2115
		add esi,buf2d_data ;указатель на нижнюю линию
2116
		shr ebx,1 ;кол. линейных циклов
2117
		shl edx,1
2118
		mov [line_2byte],edx
2119
		mov edi,buf2d_data
2120
		xchg edi,esi
2121
		cld
2122
		.flip_32:
2123
		cmp ebx,0
2124
		jle .end_32
2125
		mov ecx,[line_pix]
2126
align 4
2127
		@@:
2128
			lodsd
2129
			mov edx,dword[edi]
2130
			mov dword[esi-4],edx
2131
			stosd
2132
			loop @b
2133
		sub edi,[line_2byte]
2134
		dec ebx
2135
		jmp .flip_32
2136
	.end_32:
2137
	popad
2138
	ret
3040 IgorA 2139
endp
2140
 
2141
align 4
1535 IgorA 2142
proc buf_img_wdiv2, buf_struc:dword
2143
	pushad
2144
	mov edi,dword[buf_struc]
2927 IgorA 2145
	cmp buf2d_bits,8
2146
	jne @f
2147
		mov eax,buf2d_w
2148
		mov ecx,buf2d_h
2149
		imul ecx,eax
2150
		stdcall img_8b_wdiv2, buf2d_data,ecx
2151
	@@:
1535 IgorA 2152
	cmp buf2d_bits,24
2927 IgorA 2153
	jne @f
1535 IgorA 2154
		mov eax,buf2d_w
2155
		mov ecx,buf2d_h
2156
		imul ecx,eax
2157
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
2927 IgorA 2158
	@@:
2920 IgorA 2159
	cmp buf2d_bits,32
2927 IgorA 2160
	jne @f
2920 IgorA 2161
		mov eax,buf2d_w
2162
		mov ecx,buf2d_h
2163
		imul ecx,eax
2927 IgorA 2164
		stdcall img_rgba32_wdiv2, buf2d_data,ecx
2165
	@@:
1535 IgorA 2166
	popad
2167
	ret
2168
endp
2169
 
2170
;input:
2927 IgorA 2171
;data_8b - pointer to rgb data
2172
;size - count img pixels (size img data / 3(rgb) )
2173
align 4
2174
proc img_8b_wdiv2 data_8b:dword, size:dword
2175
	mov eax,dword[data_8b]
2176
	mov ecx,dword[size] ;ecx = size
2177
	cld
2178
	@@: ;затемнение цвета пикселей
2179
		shr byte[eax],1
2180
		inc eax
2181
		loop @b
2182
 
2183
	mov eax,dword[data_8b]
2184
	mov ecx,dword[size] ;ecx = size
2185
	shr ecx,1
2186
	@@: ;сложение цветов пикселей
2187
		mov bl,byte[eax+1] ;копируем цвет соседнего пикселя
2188
		add byte[eax],bl
2189
		add eax,2
2190
		loop @b
2191
 
2192
	mov eax,dword[data_8b]
2193
	inc eax
2194
	mov ebx,eax
2195
	inc ebx
2196
	mov ecx,dword[size] ;ecx = size
2197
	shr ecx,1
2198
	dec ecx ;лишний пиксель
2199
	@@: ;поджатие пикселей
2200
		mov dl,byte[ebx]
2201
		mov byte[eax],dl
2202
 
2203
		inc eax
2204
		add ebx,2
2205
		loop @b
2206
	ret
2207
endp
2208
 
2209
;input:
1535 IgorA 2210
;data_rgb - pointer to rgb data
2211
;size - count img pixels (size img data / 3(rgb) )
2212
align 4
2213
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
2214
  mov eax,dword[data_rgb]
2215
  mov ecx,dword[size] ;ecx = size
2216
  lea ecx,[ecx+ecx*2]
2217
  cld
2218
  @@: ;затемнение цвета пикселей
1538 IgorA 2219
		shr byte[eax],1
2220
		inc eax
2221
		loop @b
1535 IgorA 2222
 
2223
  mov eax,dword[data_rgb]
2224
  mov ecx,dword[size] ;ecx = size
2225
  shr ecx,1
2226
  @@: ;сложение цветов пикселей
1538 IgorA 2227
		mov bx,word[eax+3] ;копируем цвет соседнего пикселя
2228
		add word[eax],bx
2229
		mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
2230
		add byte[eax+2],bl
2231
		add eax,6 ;=2*3
2232
		loop @b
1535 IgorA 2233
 
2234
  mov eax,dword[data_rgb]
2235
  add eax,3
2236
  mov ebx,eax
2237
  add ebx,3
2238
  mov ecx,dword[size] ;ecx = size
2239
  shr ecx,1
2240
  dec ecx ;лишний пиксель
2241
  @@: ;поджатие пикселей
1538 IgorA 2242
		mov edx,dword[ebx]
2243
		mov word[eax],dx
2244
		shr edx,16
2245
		mov byte[eax+2],dl
1535 IgorA 2246
 
1538 IgorA 2247
		add eax,3
2248
		add ebx,6
2249
		loop @b
1535 IgorA 2250
  ret
2251
endp
2252
 
2920 IgorA 2253
;input:
2927 IgorA 2254
;data_rgba - pointer to rgba data
2255
;size - count img pixels (size img data / 4(rgba) )
1535 IgorA 2256
align 4
2927 IgorA 2257
proc img_rgba32_wdiv2 data_rgba:dword, size:dword
2258
	mov eax,dword[data_rgba]
2920 IgorA 2259
 
2927 IgorA 2260
	mov eax,dword[data_rgba]
2920 IgorA 2261
	mov ebx,eax
2262
	add ebx,4
2263
	mov ecx,dword[size] ;ecx = size
2264
	shr ecx,1
2265
	@@: ;смешивание цветов пикселей
2266
		call combine_colors_1
2267
		mov [eax],edx
2268
		add eax,8 ;=2*4
2269
		add ebx,8
2270
		loop @b
2271
 
2927 IgorA 2272
	mov eax,dword[data_rgba]
2920 IgorA 2273
	add eax,4
2274
	mov ebx,eax
2275
	add ebx,4
2276
	mov ecx,dword[size] ;ecx = size
2277
	shr ecx,1
2278
	dec ecx ;лишний пиксель
2279
	@@: ;поджатие пикселей
2280
		mov edx,dword[ebx]
2281
		mov dword[eax],edx
2282
 
2283
		add eax,4
2284
		add ebx,8
2285
		loop @b
2286
	ret
2287
endp
2288
 
3040 IgorA 2289
;description:
2290
; сжатие изображения по высоте (высота буфера не меняется)
2920 IgorA 2291
align 4
1535 IgorA 2292
proc buf_img_hdiv2, buf_struc:dword
2293
	pushad
2294
	mov edi,dword[buf_struc]
2927 IgorA 2295
	cmp buf2d_bits,8
2296
	jne @f
2297
		mov eax,buf2d_w
2298
		mov ecx,buf2d_h
2299
		imul ecx,eax
2300
		stdcall img_8b_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2301
		jmp .end_f ;edi портится в функции, потому использование buf2d_bits опасно
2927 IgorA 2302
	@@:
1535 IgorA 2303
	cmp buf2d_bits,24
2927 IgorA 2304
	jne @f
1535 IgorA 2305
		mov eax,buf2d_w
2306
		mov ecx,buf2d_h
2307
		imul ecx,eax
2308
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2309
		jmp .end_f
2927 IgorA 2310
	@@:
2920 IgorA 2311
	cmp buf2d_bits,32
2927 IgorA 2312
	jne @f
2920 IgorA 2313
		mov eax,buf2d_w
2314
		mov ecx,buf2d_h
2315
		imul ecx,eax
2316
		shl eax,2
2927 IgorA 2317
		stdcall img_rgba32_hdiv2, buf2d_data,ecx,eax
3040 IgorA 2318
		;jmp .end_f
2927 IgorA 2319
	@@:
3040 IgorA 2320
	.end_f:
1535 IgorA 2321
	popad
2322
	ret
2323
endp
2324
 
2325
;input:
2927 IgorA 2326
;data_8b - pointer to 8 bit data
2327
;size - count img pixels (size img data)
2328
;size_w - width img in pixels
2329
align 4
2330
proc img_8b_hdiv2, data_8b:dword, size:dword, size_w:dword
2331
 
2332
	mov eax,dword[data_8b] ;eax =
2333
	mov ecx,dword[size]
2334
	cld
2335
	@@: ;затемнение цвета пикселей
2336
		shr byte[eax],1
2337
		inc eax
2338
		loop @b
2339
 
2340
	mov eax,dword[data_8b] ;eax =
2341
	mov esi,dword[size_w]
2342
	mov ebx,esi
2343
	add ebx,eax
2344
	mov ecx,dword[size]  ;ecx = size
2345
	shr ecx,1
2346
	xor edi,edi
2347
	@@: ;сложение цветов пикселей
2348
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
2349
		add byte[eax],dl
2350
 
2351
		inc eax
2352
		inc ebx
2353
		inc edi
2354
		cmp edi,dword[size_w]
2355
		jl .old_line
2356
			add eax,esi
2357
			add ebx,esi
2358
			xor edi,edi
2359
		.old_line:
2360
		loop @b
2361
 
2362
 
2363
	mov eax,dword[data_8b] ;eax =
2364
	add eax,esi ;esi = width*3(rgb)
2365
	mov ebx,eax
2366
	add ebx,esi
2367
	mov ecx,dword[size] ;ecx = size
2368
	shr ecx,1
2369
	sub ecx,dword[size_w] ;лишняя строка пикселей
2370
	xor edi,edi
2371
	@@: ;поджатие пикселей
2372
		mov dl,byte[ebx] ;копируем цвет нижнего пикселя
2373
		mov byte[eax],dl
2374
 
2375
		inc eax
2376
		inc ebx
2377
		inc edi
2378
		cmp edi,dword[size_w]
2379
		jl .old_line_2
2380
			add ebx,esi
2381
			xor edi,edi
2382
		.old_line_2:
2383
		loop @b
2384
 
2385
	ret
2386
endp
2387
 
2388
;input:
1535 IgorA 2389
;data_rgb - pointer to rgb data
2390
;size - count img pixels (size img data / 3(rgb) )
2391
;size_w - width img in pixels
2392
align 4
2393
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
2394
 
2395
  mov eax,dword[data_rgb] ;eax =
2396
  mov ecx,dword[size]	  ;ecx = size
2397
  lea ecx,[ecx+ecx*2]
2398
  cld
2399
  @@: ;затемнение цвета пикселей
2400
    shr byte[eax],1
2401
    inc eax
2402
    loop @b
2403
 
2404
  mov eax,dword[data_rgb] ;eax =
2920 IgorA 2405
  mov esi,dword[size_w]
2406
  lea esi,[esi+esi*2] ;esi = width*3(rgb)
1535 IgorA 2407
  mov ebx,esi
2408
  add ebx,eax
2409
  mov ecx,dword[size]  ;ecx = size
2410
  shr ecx,1
2411
  xor edi,edi
2412
  @@: ;сложение цветов пикселей
2413
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
2414
    add word[eax],dx
2415
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
2416
    add byte[eax+2],dl
2417
 
2418
    add eax,3
2419
    add ebx,3
2420
    inc edi
2421
    cmp edi,dword[size_w]
2422
    jl .old_line
2423
      add eax,esi
2424
      add ebx,esi
2425
      xor edi,edi
2426
    .old_line:
2427
    loop @b
2428
 
2429
 
2430
  mov eax,dword[data_rgb] ;eax =
2431
  add eax,esi ;esi = width*3(rgb)
2920 IgorA 2432
  mov ebx,eax
2433
  add ebx,esi
1535 IgorA 2434
  mov ecx,dword[size] ;ecx = size
2435
  shr ecx,1
2436
  sub ecx,dword[size_w] ;лишняя строка пикселей
2437
  xor edi,edi
2438
  @@: ;поджатие пикселей
2439
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
2440
    mov word[eax],dx
2441
    shr edx,16
2442
    mov byte[eax+2],dl
2443
 
2444
    add eax,3
2445
    add ebx,3
2446
    inc edi
2447
    cmp edi,dword[size_w]
2448
    jl .old_line_2
2449
      add ebx,esi
2450
      xor edi,edi
2451
    .old_line_2:
2452
    loop @b
2453
 
2454
  ret
2455
endp
2456
 
2920 IgorA 2457
;input:
2927 IgorA 2458
;data_rgba - pointer to rgba data
2459
;size - count img pixels (size img data / 4(rgba) )
2920 IgorA 2460
;size_w_b - width img in bytes
2461
align 4
2927 IgorA 2462
proc img_rgba32_hdiv2, data_rgba:dword, size:dword, size_w_b:dword
2920 IgorA 2463
 
2927 IgorA 2464
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 2465
	mov ebx,dword[size_w_b]
2466
	add ebx,eax
2467
	mov ecx,dword[size]  ;ecx = size
2468
	shr ecx,1
2469
	xor edi,edi
2470
	@@: ;смешивание цветов пикселей
2471
		call combine_colors_1
2472
		mov dword[eax],edx
2473
 
2474
		add eax,4
2475
		add ebx,4
2476
		add edi,4
2477
		cmp edi,dword[size_w_b]
2478
		jl .old_line
2479
			add eax,dword[size_w_b]
2480
			add ebx,dword[size_w_b]
2481
			xor edi,edi
2482
		.old_line:
2483
		loop @b
2484
 
2485
 
2927 IgorA 2486
	mov eax,dword[data_rgba] ;eax =
2920 IgorA 2487
	mov ebx,dword[size_w_b]
2488
	add eax,ebx
2489
	add ebx,eax
2490
	mov ecx,dword[size] ;ecx = size
2491
	shl ecx,1
2492
	sub ecx,dword[size_w_b] ;лишняя строка пикселей
2493
	shr ecx,2
2494
	xor edi,edi
2495
	@@: ;поджатие пикселей
2496
		mov edx,dword[ebx] ;копируем цвет нижнего пикселя
2497
		mov dword[eax],edx
2498
 
2499
		add eax,4
2500
		add ebx,4
2501
		add edi,4
2502
		cmp edi,dword[size_w_b]
2503
		jl .old_line_2
2504
			add ebx,dword[size_w_b]
2505
			xor edi,edi
2506
		.old_line_2:
2507
		loop @b
2508
 
2509
	ret
2510
endp
2511
 
2512
;input:
2513
; eax - указатель на 32-битный цвет
2514
; ebx - указатель на 32-битный цвет
2515
;output:
2516
; edx - 32-битный цвет смешанный с учетом прозрачности
2517
;destroy:
2518
; esi
2519
align 4
2520
proc combine_colors_1 uses ecx edi
2521
locals
2522
	c_blye dd ?
2523
	c_green dd ?
2524
	c_red dd ?
2525
endl
2526
	movzx edi,byte[eax+3]
2527
	cmp edi,255
2528
	je .c0z
2529
	movzx esi,byte[ebx+3]
2530
	cmp esi,255
2531
	je .c1z
2927 IgorA 2532
	cmp edi,esi
2533
	je .c0_c1
2920 IgorA 2534
 
2535
	;переворачиваем значения прозрачностей
2536
	neg edi
2537
	inc edi
2538
	add edi,255
2539
	neg esi
2540
	inc esi
2541
	add esi,255
2542
 
2543
	movzx ecx,byte[eax]
2544
	imul ecx,edi
2545
	mov [c_blye],ecx
2546
	movzx ecx,byte[ebx]
2547
	imul ecx,esi
2548
	add [c_blye],ecx
2549
 
2550
	movzx ecx,byte[eax+1]
2551
	imul ecx,edi
2552
	mov [c_green],ecx
2553
	movzx ecx,byte[ebx+1]
2554
	imul ecx,esi
2555
	add [c_green],ecx
2556
 
2557
	movzx ecx,byte[eax+2]
2558
	imul ecx,edi
2559
	mov [c_red],ecx
2560
	movzx ecx,byte[ebx+2]
2561
	imul ecx,esi
2562
	add [c_red],ecx
2563
 
2564
push eax ebx
2565
	xor ebx,ebx
2566
	mov eax,[c_red]
2567
	xor edx,edx
2568
	mov ecx,edi
2569
	add ecx,esi
2570
	div ecx
2571
	mov bl,al
2572
	shl ebx,16
2573
	mov eax,[c_green]
2574
	xor edx,edx
2575
	div ecx
2576
	mov bh,al
2577
	mov eax,[c_blye]
2578
	xor edx,edx
2579
	div ecx
2580
	mov bl,al
2581
 
2582
	shr ecx,1
2583
	;переворачиваем значения прозрачности
2584
	neg ecx
2585
	inc ecx
2586
	add ecx,255
2587
 
2588
	shl ecx,24
2589
	add ebx,ecx
2590
	mov edx,ebx
2591
pop ebx eax
2592
 
2593
	jmp .end_f
2927 IgorA 2594
	.c0_c1: ;если прозрачности обоих цветов совпадают
2595
		mov edx,dword[eax]
2596
		shr edx,1
2597
		and edx,011111110111111101111111b
2598
		mov esi,dword[ebx]
2599
		shr esi,1
2600
		and esi,011111110111111101111111b
2601
		add edx,esi
2602
		ror edi,8 ;перемещаем значение прозрачности в старший байт edi
2603
		or edx,edi
2604
		jmp .end_f
2920 IgorA 2605
	.c0z: ;если цвет в eax прозрачный
2606
		mov edx,dword[ebx]
2607
		movzx edi,byte[ebx+3]
2608
		jmp @f
2609
	.c1z: ;если цвет в ebx прозрачный
2610
		mov edx,dword[eax]
2611
	@@:
2612
		add edi,255 ;делаем цвет на половину прозрачным
2613
		shr edi,1
2614
		cmp edi,255
2615
		jl @f
2616
			mov edi,255 ;максимальная прозрачность не более 255
2617
		@@:
2618
		shl edi,24
2619
		and edx,0xffffff ;снимаем старую прозрачность
2620
		add edx,edi
2621
	.end_f:
2622
	ret
2623
endp
2624
 
1535 IgorA 2625
;преобразование буфера из 24-битного в 8-битный
2626
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
2627
align 4
2628
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
2629
	pushad
2630
	mov edi,dword[buf_struc]
2631
	cmp buf2d_bits,24
2632
	jne .error
2633
		mov eax,buf2d_w
2634
		mov ecx,buf2d_h
2635
		imul ecx,eax
2636
		mov esi,ecx
2637
		;ebx - память из которой копируется
2638
		;edx - память куда копируется
2639
		mov edx,buf2d_data
2640
		mov ebx,edx
2641
		cmp [spectr],3
2642
		jge @f
2643
			add ebx,[spectr]
2644
		@@:
2645
			mov al,byte[ebx]
2646
			mov byte[edx],al
2647
			add ebx,3
2648
			inc edx
2649
			loop @b
2650
		mov buf2d_bits,8
2651
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
2652
		jmp .end_conv
2653
	.error:
2654
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
2655
	.end_conv:
2656
	popad
2657
	ret
2658
endp
2659
 
2660
;преобразование буфера из 24-битного в 32-битный
2661
align 4
2662
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
2663
	pushad
2664
	mov edi,dword[buf_struc]
2665
	cmp buf2d_bits,24
2666
	jne .error1
2667
		mov ecx,buf2d_w
2668
		mov ebx,buf2d_h
2669
		imul ebx,ecx
2670
		mov ecx,ebx ;ecx = size  8 b
2671
		shl ebx,2   ;ebx = size 32 b
2672
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
2673
		mov buf2d_data,eax ;на случай если изменился указатель на данные
2674
		mov buf2d_bits,32
2675
		mov edx,ebx ;edx = size 32 b
2676
		sub ebx,ecx ;ebx = size 24 b
2677
		mov eax,ecx
2678
		;eax - размер  8 битных данных
2679
		;ebx - размер 24 битных данных
2680
		;edx - размер 32 битных данных
2681
		add ebx,buf2d_data
2682
		add edx,buf2d_data
2683
		mov edi,dword[buf_str8]
2684
		cmp buf2d_bits,8
2685
		jne .error2
2686
		add eax,buf2d_data
2687
		mov edi,edx
2688
		;eax - указатель на конец  8 битных данных
2689
		;ebx - указатель на конец 24 битных данных
2690
		;edi - указатель на конец 32 битных данных
2691
		@@:
2692
			sub edi,4 ;отнимаем в начале цикла,
2693
			sub ebx,3 ; потому, что указатели стоят
2694
			dec eax   ; за пределами буферов
2695
			mov edx,dword[ebx]
2696
			mov dword[edi],edx
2697
			mov dl,byte[eax]
2698
			mov byte[edi+3],dl
2699
			loop @b
2700
 
2701
		jmp .end_conv
2702
	.error1:
2703
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
2704
		jmp .end_conv
2705
	.error2:
2706
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
2707
	.end_conv:
2708
	popad
2709
	ret
2710
endp
2711
 
2712
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
2713
; указываются координаты вставки буфера buf_source относительно buf_destination
2714
; прозрачность при копировании не учитывается
2715
align 4
2716
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2717
	locals
2718
		right_bytes dd ?
2719
	endl
2720
	pushad
2721
 
2722
	mov edi,[buf_source]
2723
	cmp buf2d_bits,24
2724
	je .sou24
2725
	cmp buf2d_bits,32
2726
	je .sou32
2727
		jmp .copy_end ;формат буфера не поодерживается
2728
 
1648 IgorA 2729
	.sou24: ;в источнике 24 битная картинка
1535 IgorA 2730
	mov eax,buf2d_w
2731
	mov edx,buf2d_h ;высота копируемой картинки
2732
	mov esi,buf2d_data ;данные копируемой картинки
2733
 
2734
	mov edi,[buf_destination]
2735
	cmp buf2d_bits,24
2736
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2737
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2738
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2739
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2740
		mov ebx,buf2d_h ;ebx - высота основного буфера
2741
		mov ecx,[coord_y]
2422 IgorA 2742
		cmp ecx,0
2743
		jge @f
2744
			;если координата coord_y<0 (1-я настройка)
2745
			add edx,ecx ;уменьшаем высоту копируемой картинки
2746
			cmp edx,0
2747
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2748
			neg ecx
2749
			;inc ecx
2750
			imul ecx,eax
2751
			lea ecx,[ecx+ecx*2] ;по 3 байта на пиксель
2752
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2753
			xor ecx,ecx ;обнуляем координату coord_y
2754
		@@:
1535 IgorA 2755
		cmp ecx,ebx
2756
		jge .copy_end ;если координата 'y' больше высоты буфера
2757
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2758
		cmp ecx,ebx
2759
		jle @f
2760
			sub ecx,ebx
2761
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2762
		@@:
2763
		mov ebx,buf2d_w
2422 IgorA 2764
		mov ecx,[coord_y] ;ecx используем для временных целей
2765
		cmp ecx,0
2766
		jg .end_otr_c_y_24
2767
			;если координата coord_y<=0 (2-я настройка)
2768
			mov ecx,[coord_x]
2769
			jmp @f
2770
		.end_otr_c_y_24:
2771
		imul ecx,ebx
1535 IgorA 2772
		add ecx,[coord_x]
2422 IgorA 2773
		@@:
1535 IgorA 2774
		lea ecx,[ecx+ecx*2]
2775
		add ecx,buf2d_data
2776
		sub ebx,eax
2777
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2778
 
2779
	mov [right_bytes],0
2780
	mov ecx,[coord_x]
2781
	cmp ecx,ebx
2782
	jl @f
2783
		sub ecx,ebx
2784
		sub eax,ecx ;укорачиваем копируемую строку
2785
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2786
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2787
		mov [right_bytes],ecx
2788
	@@:
2789
 
2790
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
2791
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2792
 
2793
	cld
2794
	cmp [right_bytes],0
2795
	jg .copy_1
2796
	.copy_0: ;простое копирование
2797
		mov ecx,eax
2798
		rep movsb
2799
		add edi,ebx
2800
		dec edx
2801
		cmp edx,0
2802
		jg .copy_0
2803
	jmp .copy_end
2804
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2805
		mov ecx,eax
2806
		rep movsb
2807
		add edi,ebx
2808
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2809
		dec edx
2810
		cmp edx,0
2811
		jg .copy_1
2812
	jmp .copy_end
2813
 
2814
	.sou32: ;в источнике 32 битная картинка
2815
	mov eax,buf2d_w
2816
	mov edx,buf2d_h ;высота копируемой картинки
2817
	mov esi,buf2d_data ;данные копируемой картинки
2818
 
2819
	mov edi,[buf_destination]
2820
	cmp buf2d_bits,24
2821
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2822
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2823
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2824
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2825
		mov ebx,buf2d_h ;ebx - высота основного буфера
2826
		mov ecx,[coord_y]
2422 IgorA 2827
		cmp ecx,0
2828
		jge @f
2829
			;если координата coord_y<0 (1-я настройка)
2830
			add edx,ecx ;уменьшаем высоту копируемой картинки
2831
			cmp edx,0
2832
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2833
			neg ecx
2834
			;inc ecx
2835
			imul ecx,eax
2836
			shl ecx,2 ;по 4 байта на пиксель
2837
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2838
			xor ecx,ecx ;обнуляем координату coord_y
2839
		@@:
1535 IgorA 2840
		cmp ecx,ebx
2841
		jge .copy_end ;если координата 'y' больше высоты буфера
2842
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2843
		cmp ecx,ebx
2844
		jle @f
2845
			sub ecx,ebx
2846
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2847
		@@:
2848
		mov ebx,buf2d_w
2422 IgorA 2849
		;mov ecx,ebx ;ecx используем для временных целей
2850
		;imul ecx,[coord_y]
2851
		;add ecx,[coord_x]
2852
		mov ecx,[coord_y] ;ecx используем для временных целей
2853
		cmp ecx,0
2854
		jg .end_otr_c_y_32
2855
			;если координата coord_y<=0 (2-я настройка)
2856
			mov ecx,[coord_x]
2857
			jmp @f
2858
		.end_otr_c_y_32:
2859
		imul ecx,ebx
1535 IgorA 2860
		add ecx,[coord_x]
2422 IgorA 2861
		@@:
1535 IgorA 2862
		lea ecx,[ecx+ecx*2]
2863
		add ecx,buf2d_data
2864
		sub ebx,eax
2865
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2866
 
2867
	mov [right_bytes],0
2868
	mov ecx,[coord_x]
2869
	cmp ecx,ebx
2870
	jl @f
2871
		sub ecx,ebx
2872
		sub eax,ecx ;укорачиваем копируемую строку
2873
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2874
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2875
		mov [right_bytes],ecx
2876
	@@:
2877
 
2878
	;eax - колличество пикселей в 1-й строке копируемой картинки
2879
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2880
 
2881
	cld
2882
	cmp [right_bytes],0
2883
	jg .copy_3
2884
	.copy_2: ;простое копирование
2885
		mov ecx,eax
2886
		@@:
2887
			movsw
2888
			movsb
2889
			inc esi
2890
			loop @b
2891
		add edi,ebx
2892
		dec edx
2893
		cmp edx,0
2894
		jg .copy_2
2895
	jmp .copy_end
2896
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
2897
		mov ecx,eax
2898
		@@:
2899
			movsw
2900
			movsb
2901
			inc esi
2902
			loop @b
2903
		add edi,ebx
2904
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2905
		dec edx
2906
		cmp edx,0
2907
		jg .copy_3
2908
 
2909
	.copy_end:
2910
	popad
2911
	ret
2912
endp
2913
 
2914
;input:
2915
; esi = pointer to color1 + transparent
2916
; edi = pointer to background color2
2917
;output:
2918
; [edi] = combine color
2919
align 4
2920 IgorA 2920
combine_colors_0:
1535 IgorA 2921
	push ax bx cx dx
2922
	mov bx,0x00ff ;---get transparent---
2748 IgorA 2923
	movzx cx,byte[esi+3] ;pro
1535 IgorA 2924
	sub bx,cx ;256-pro
1653 IgorA 2925
	;---blye---
2748 IgorA 2926
	movzx ax,byte[esi]
1535 IgorA 2927
	imul ax,bx
2748 IgorA 2928
	movzx dx,byte[edi]
1535 IgorA 2929
	imul dx,cx
2930
	add ax,dx
1653 IgorA 2931
	mov byte[edi],ah
1535 IgorA 2932
	;---green---
2748 IgorA 2933
	movzx ax,byte[esi+1]
1535 IgorA 2934
	imul ax,bx
2748 IgorA 2935
	movzx dx,byte[edi+1]
1535 IgorA 2936
	imul dx,cx
2937
	add ax,dx
2938
	mov byte[edi+1],ah
1653 IgorA 2939
	;---red---
2748 IgorA 2940
	movzx ax,byte[esi+2]
1535 IgorA 2941
	imul ax,bx
2748 IgorA 2942
	movzx dx,byte[edi+2]
1535 IgorA 2943
	imul dx,cx
2944
	add ax,dx
1653 IgorA 2945
	mov byte[edi+2],ah
1535 IgorA 2946
 
2947
	pop dx cx bx ax
2948
	ret
2949
 
2950
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
2951
; указываются координаты вставки буфера buf_source относительно buf_destination
2952
; при копировании учитывается прозрачность
2953
align 4
2954
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2955
	locals
2927 IgorA 2956
		lost_bytes dd ?
1535 IgorA 2957
	endl
2958
	pushad
2959
 
2960
	mov edi,[buf_source]
2961
	cmp buf2d_bits,32
2962
	jne .copy_end ;формат буфера не поодерживается
2963
	mov eax,buf2d_w
2964
	mov edx,buf2d_h ;высота копируемой картинки
2965
	mov esi,buf2d_data ;данные копируемой картинки
2966
 
2967
	mov edi,[buf_destination]
2968
	cmp buf2d_bits,24
2969
	jne .copy_end ;формат буфера не поодерживается
2970
		mov ebx,buf2d_h ;ebx - высота основного буфера
2971
		mov ecx,[coord_y]
2383 IgorA 2972
		cmp ecx,0
2973
		jge @f
2974
			;если координата coord_y<0 (1-я настройка)
2975
			add edx,ecx ;уменьшаем высоту копируемой картинки
2976
			cmp edx,0
2977
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2978
			neg ecx
2979
			;inc ecx
2980
			imul ecx,eax
2422 IgorA 2981
			shl ecx,2 ;по 4 байта на пиксель
2383 IgorA 2982
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2983
			xor ecx,ecx ;обнуляем координату coord_y
2984
		@@:
1535 IgorA 2985
		cmp ecx,ebx
2986
		jge .copy_end ;если координата 'y' больше высоты буфера
2987
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2988
		cmp ecx,ebx
2989
		jle @f
2990
			sub ecx,ebx
2991
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2992
		@@:
2993
		mov ebx,buf2d_w
2994
		mov ecx,ebx ;ecx используем для временных целей
2383 IgorA 2995
		cmp [coord_y],0
2996
		jg .end_otr_c_y
2997
			;если координата coord_y<=0 (2-я настройка)
2998
			mov ecx,[coord_x]
2999
			jmp @f
3000
		.end_otr_c_y:
1535 IgorA 3001
		imul ecx,[coord_y]
3002
		add ecx,[coord_x]
2383 IgorA 3003
		@@:
1535 IgorA 3004
		lea ecx,[ecx+ecx*2]
3005
		add ecx,buf2d_data
3006
		sub ebx,eax
3007
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3008
 
2927 IgorA 3009
	mov dword[lost_bytes],0
1535 IgorA 3010
	mov ecx,[coord_x]
2927 IgorA 3011
	cmp ecx,0
3012
	jge @f
3013
		neg ecx
3014
		;inc ecx
3015
		cmp eax,ecx ;eax - ширина копируемой картинки
3016
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
3017
		shl ecx,2
3018
		mov [lost_bytes],ecx
3019
		add esi,ecx
3020
		shr ecx,2
3021
		sub eax,ecx ;укорачиваем копируемую строку
3022
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3023
		lea ecx,[ecx+ecx*2]
3024
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3025
		xor ecx,ecx
3026
	@@:
1535 IgorA 3027
	cmp ecx,ebx
2927 IgorA 3028
	jle @f
1535 IgorA 3029
		sub ecx,ebx
3030
		sub eax,ecx ;укорачиваем копируемую строку
3031
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2927 IgorA 3032
		shl ecx,2 ;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
3033
		add [lost_bytes],ecx
1535 IgorA 3034
	@@:
3035
 
2927 IgorA 3036
;	mov [right_bytes],0
3037
;	mov ecx,[coord_x]
3038
;	cmp ecx,ebx
3039
;	jl @f
3040
;		sub ecx,ebx
3041
;		sub eax,ecx ;укорачиваем копируемую строку
3042
;		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3043
;		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
3044
;		mov [right_bytes],ecx
3045
;	@@:
3046
 
1535 IgorA 3047
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2658 IgorA 3048
 
1535 IgorA 3049
	cld
2927 IgorA 3050
	cmp [lost_bytes],0
1535 IgorA 3051
	jg .copy_1
3052
	.copy_0: ;простое копирование
3053
		mov ecx,eax
3054
		@@:
2920 IgorA 3055
			call combine_colors_0
1535 IgorA 3056
			add edi,3
3057
			add esi,4
3058
			loop @b
3059
		add edi,ebx
3060
		dec edx
3061
		cmp edx,0
3062
		jg .copy_0
3063
	jmp .copy_end
3064
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
3065
		mov ecx,eax
3066
		@@:
2920 IgorA 3067
			call combine_colors_0
1535 IgorA 3068
			add edi,3
3069
			add esi,4
3070
			loop @b
3071
		add edi,ebx
2927 IgorA 3072
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 3073
		dec edx
3074
		cmp edx,0
3075
		jg .copy_1
3076
 
3077
	.copy_end:
3078
	popad
3079
	ret
3080
endp
3081
 
3082
;input:
3083
; ebx - color1
3084
; esi = pointer to transparent
3085
; edi = pointer to background color2
3086
;output:
3087
; [edi] = combine color
3088
align 4
3089
combine_colors_2:
3090
	push ax ebx cx dx si
3091
	mov cl,byte[esi] ;pro
3092
	xor ch,ch
3093
	mov si,0x00ff ;---get transparent---
3094
	sub si,cx ;256-pro
3095
 
1653 IgorA 3096
		;---blye---
2748 IgorA 3097
		movzx ax,bl
1535 IgorA 3098
		shr ebx,8
3099
		imul ax,si
2748 IgorA 3100
		movzx dx,byte[edi]
1535 IgorA 3101
		imul dx,cx
3102
		add ax,dx
1653 IgorA 3103
		mov byte[edi],ah
1535 IgorA 3104
		;---green---
2748 IgorA 3105
		movzx ax,bl
1535 IgorA 3106
		shr ebx,8
3107
		imul ax,si
2748 IgorA 3108
		movzx dx,byte[edi+1]
1535 IgorA 3109
		imul dx,cx
3110
		add ax,dx
3111
		mov byte[edi+1],ah
3112
		;---red---
2748 IgorA 3113
		movzx ax,bl
1535 IgorA 3114
		imul ax,si
2748 IgorA 3115
		movzx dx,byte[edi+2]
1535 IgorA 3116
		imul dx,cx
3117
		add ax,dx
1653 IgorA 3118
		mov byte[edi+2],ah
1535 IgorA 3119
 
3120
	pop si dx cx ebx ax
3121
	ret
3122
 
3123
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
3124
; указываются координаты вставки буфера buf_source относительно buf_destination
3125
align 4
3126
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
3127
	locals
2383 IgorA 3128
		lost_bytes dd ? ;число потерянных байтов в строке копируемого изображеня (тех что не влазят в буфер)
1535 IgorA 3129
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
3130
	endl
3131
	pushad
3132
 
3133
	mov edi,[buf_source]
3134
	cmp buf2d_bits,8
3135
	jne .error1 ;формат буфера не поодерживается
2383 IgorA 3136
	mov eax,buf2d_w ;ширина копируемой картинки
1535 IgorA 3137
	mov edx,buf2d_h ;высота копируемой картинки
3138
	mov esi,buf2d_data ;данные копируемой картинки
3139
 
3140
	mov edi,[buf_destination]
3141
	cmp buf2d_bits,24
3142
	jne .error2 ;формат буфера не поодерживается
1642 IgorA 3143
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
3144
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 3145
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 3146
		mov ebx,buf2d_h ;ebx - высота основного буфера
3147
		mov ecx,[coord_y]
2367 IgorA 3148
		cmp ecx,0
3149
		jge @f
3150
			;если координата coord_y<0 (1-я настройка)
3151
			add edx,ecx ;уменьшаем высоту копируемой картинки
2383 IgorA 3152
			cmp edx,0
3153
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2367 IgorA 3154
			neg ecx
3155
			;inc ecx
3156
			imul ecx,eax
3157
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
3158
			xor ecx,ecx ;обнуляем координату coord_y
3159
		@@:
1535 IgorA 3160
		cmp ecx,ebx
3161
		jge .copy_end ;если координата 'y' больше высоты буфера
3162
		add ecx,edx ;ecx - нижняя координата копируемой картинки
3163
		cmp ecx,ebx
3164
		jle @f
3165
			sub ecx,ebx
3166
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
3167
		@@:
3168
		mov ebx,buf2d_w
2367 IgorA 3169
		mov ecx,[coord_y] ;ecx используем для временных целей
3170
		cmp ecx,0
2383 IgorA 3171
		jg .end_otr_c_y
3172
			;если координата coord_y<=0 (2-я настройка)
2367 IgorA 3173
			mov ecx,[coord_x]
3174
			jmp @f
3175
		.end_otr_c_y:
3176
		imul ecx,ebx
1535 IgorA 3177
		add ecx,[coord_x]
2367 IgorA 3178
		@@:
1535 IgorA 3179
		lea ecx,[ecx+ecx*2]
2383 IgorA 3180
		add ecx,buf2d_data ;buf2d_data данные основного буфера
3181
		sub ebx,eax ;ebx - ширина основного буфера минус ширина рисуемого буфера
1535 IgorA 3182
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3183
 
2383 IgorA 3184
	mov dword[lost_bytes],0
1535 IgorA 3185
	mov ecx,[coord_x]
2383 IgorA 3186
	cmp ecx,0
3187
	jge @f
3188
		neg ecx
3189
		;inc ecx
3190
		cmp eax,ecx ;eax - ширина копируемой картинки
3191
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2927 IgorA 3192
		mov [lost_bytes],ecx
2383 IgorA 3193
		sub eax,ecx ;укорачиваем копируемую строку
3194
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3195
		add esi,ecx
3196
		lea ecx,[ecx+ecx*2]
3197
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
3198
		xor ecx,ecx
3199
	@@:
1535 IgorA 3200
	cmp ecx,ebx
2383 IgorA 3201
	jle @f
1535 IgorA 3202
		sub ecx,ebx
3203
		sub eax,ecx ;укорачиваем копируемую строку
3204
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
3205
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2383 IgorA 3206
		add [lost_bytes],ecx
1535 IgorA 3207
	@@:
3208
 
3209
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
3210
	mov [dest_w_bytes],ebx
3211
	mov ebx,[color]
3212
 
3213
	cld
2383 IgorA 3214
	cmp dword[lost_bytes],0
1535 IgorA 3215
	jg .copy_1
3216
	.copy_0: ;простое копирование
3217
		mov ecx,eax
3218
		@@:
3219
			call combine_colors_2
3220
			add edi,3
3221
			inc esi
3222
			loop @b
3223
		add edi,[dest_w_bytes]
3224
		dec edx
3225
		cmp edx,0
3226
		jg .copy_0
3227
	jmp .copy_end
2383 IgorA 3228
	.copy_1: ;не простое копирование (картинка вылазит за левую и/или правую сторону)
1535 IgorA 3229
		mov ecx,eax
3230
		@@:
3231
			call combine_colors_2
3232
			add edi,3
3233
			inc esi
3234
			loop @b
3235
		add edi,[dest_w_bytes]
2383 IgorA 3236
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 3237
		dec edx
3238
		cmp edx,0
3239
		jg .copy_1
3240
 
3241
	jmp .copy_end
3242
	.error1:
3243
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
3244
		jmp .copy_end
3245
	.error2:
3246
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
3247
	.copy_end:
3248
	popad
3249
	ret
3250
endp
3251
 
3252
;преобразование 8-битного буфера размером 16*16 в размер 1*256 символов
3253
align 4
3254
proc buf_convert_text_matrix, buf_struc:dword
3255
	locals
3256
		tmp_mem dd ?
3257
		c1 dw ?
3258
		c2 dd ?
3259
		c3 dw ?
3260
	endl
3261
	pushad
3262
	mov edi,dword[buf_struc]
3263
	cmp buf2d_bits,8
3264
	jne .error
3265
		mov ecx,buf2d_h
3266
		mov ebx,ecx
3267
		shr ebx,4 ;предполагаем что в буфере 16 строк с символами, потому делим на 2^4
3268
		mov edx,buf2d_w
3269
		imul ecx,edx ;ecx = size  8 b
3270
		invoke mem.alloc,ecx ;выделяем временную память
3271
		mov [tmp_mem],eax ;eax - new memory
3272
 
3273
		shr edx,4 ;предполагаем что в буфере 16 колонок с символами, потому делим на 2^4
3274
		mov eax,ebx
3275
		imul ebx,edx ;вычисляем кооличество пикселей на 1 символ
3276
		;eax = bhe - высота буквы
3277
		;ebx = bwi*bhe - колличество пикселей в 1-й букве
3278
		;edx = bwi - ширина буквы
3279
		;ecx,esi,edi - используются в цикле .c_0
3280
		shr buf2d_w,4
3281
		shl buf2d_h,4 ;преобразовываем размеры буфера
3282
 
3283
		cld
3284
		mov esi,buf2d_data
3285
		mov edi,[tmp_mem]
3286
		mov word[c3],16
3287
		.c_3:
3288
			mov dword[c2],eax
3289
			.c_2:
3290
				mov word[c1],16
3291
				.c_1:
3292
					mov ecx,edx ;.c_0:
3293
					rep movsb
3294
					add edi,ebx
3295
					sub edi,edx ;edi+=(bwi*bhe-bwi)
3296
					dec word[c1]
3297
					cmp word[c1],0
3298
					jg .c_1
3299
				add edi,edx
3300
				shl ebx,4
3301
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
3302
				shr ebx,4
3303
				dec dword[c2]
3304
				cmp dword[c2],0
3305
				jg .c_2
3306
			sub edi,ebx
3307
			shl ebx,4
3308
			add edi,ebx ;edi+=(15*bwi*bhe)
3309
			shr ebx,4
3310
			dec word[c3]
3311
			cmp word[c3],0
3312
			jg .c_3
3313
 
3314
		mov edi,dword[buf_struc] ;копирование новой матрицы в основной буфер
3315
		mov edi,buf2d_data
3316
		mov esi,[tmp_mem]
3317
		mov ecx,ebx
3318
		shl ecx,8
3319
		rep movsb
3320
		invoke mem.free,[tmp_mem] ;чистим временную память
3321
		jmp .end_conv
3322
	.error:
3323
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
3324
	.end_conv:
3325
	popad
3326
	ret
3327
endp
3328
 
3329
align 4
3330
buf_s_matr buf_2d_header ? ;локальная матрица символа
3331
 
3332
align 4
3333
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
3334
	locals
3335
		buf_t_matr_offs dd ?
3336
	endl
3337
	pushad
3338
	mov edi,dword[buf_struc]
3339
	cmp buf2d_bits,24
3340
	jne .error2
3341
	mov edi,dword[buf_t_matr]
3342
	cmp buf2d_bits,8
3343
	jne .error1
3344
		mov edx,buf2d_data
3345
		mov [buf_t_matr_offs],edx
3346
		mov ecx,BUF_STRUCT_SIZE ;копируем структуру текстовой матрицы
3347
		mov esi,edi
3348
		lea edi,[buf_s_matr]
3349
		cld
3350
		rep movsb
3351
		lea edi,[buf_s_matr]
3352
		shr buf2d_h,8 ;делим высоту символьного буфера на 256, для нахождения высоты 1-го символа
3353
		mov ebx,buf2d_h ;берем высоту символа
3354
		mov ecx,buf2d_w ;берем ширину символа
3355
 
3356
		mov eax,[coord_x]
3357
		mov esi,[text]
3358
		cmp byte[esi],0
3359
		je .end_draw ;если пустая строка
3360
		@@:
3361
			xor edx,edx
3362
			mov dl,byte[esi] ;берем код символа
3363
			imul edx,ebx ;умножаем его на высоту символа
3364
			imul edx,ecx ;умножаем на ширину символа
3365
			add edx,[buf_t_matr_offs] ;прибавляем смещение 0-го символа, т. е. получается смещение выводимого символа
3366
			mov buf2d_data,edx ;в локальный буфер символа, ставим указатель на нужный символ из буфера buf_t_matr
3367
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
3368
			add eax,ecx
3369
			.new_s:
3370
				inc esi
3371
				cmp byte[esi],13
3372
				jne .no_13
3373
					mov eax,[coord_x]
3374
					add [coord_y],ebx
3375
					jmp .new_s
3376
				.no_13:
3377
			cmp byte[esi],0
3378
			jne @b
3379
		jmp .end_draw
3380
	.error1:
3381
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
3382
		jmp .end_draw
3383
	.error2:
3384
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
3385
	.end_draw:
3386
	popad
3387
	ret
3388
endp
3389
 
3390
align 4
3391
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
3392
	pushad
3393
	mov eax,63
3394
	mov ebx,1
3395
 
3396
	mov esi,[fun]
3397
	@@:
3398
		mov cl,byte[esi]
3399
		int 0x40
3400
		inc esi
3401
		cmp byte[esi],0
3402
		jne @b
3403
	mov cl,':'
3404
	int 0x40
3405
	mov cl,' '
3406
	int 0x40
3407
	mov esi,[mes]
3408
	@@:
3409
		mov cl,byte[esi]
3410
		int 0x40
3411
		inc esi
3412
		cmp byte[esi],0
3413
		jne @b
3414
	popad
3415
	ret
3416
endp
3417
 
3418
;input:
3419
; ebp+8  = p0
3420
; ebp+12 = p1
3421
align 4
3422
line_len4i:
3423
	push ebp
3424
	mov ebp,esp
3425
		fild word [ebp+8]
3426
		fisub word [ebp+12]
3427
		fmul st0,st0 ;st0=x^2
3428
		fild word [ebp+10]
3429
		fisub word [ebp+14]
3430
		fmul st0,st0 ;st0=y^2
5389 IgorA 3431
		faddp
1535 IgorA 3432
		fsqrt
3433
		fstp dword [ebp+12]
3434
	pop ebp
3435
	ret 4 ;8
3436
 
3437
align 4
1727 IgorA 3438
proc buf_curve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
1535 IgorA 3439
	locals
3440
		delt_t dd ?
3441
		opr_param dd ?
3442
		v_poi_0 dd ?
3443
	endl
3444
	pushad
3445
 
3446
;float t, xt,yt;
3447
;for(t=.0;t<1.;t+=.005){
3448
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
3449
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
3450
;  dc.SetPixel(xt,yt,255L);
3451
;}
3452
 
1727 IgorA 3453
	mov edx,[color] ;set curve color
1535 IgorA 3454
	mov edi,[buffer]
3455
	xor ebx,ebx
3456
	xor ecx,ecx
3457
 
3458
	finit
5389 IgorA 3459
	fldz
1535 IgorA 3460
 
3461
	; calculate delta t
3462
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
3463
	fadd dword[esp]
3464
	add esp,4 ;pop ...
3465
 
3466
	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
3467
	fadd dword[esp]
3468
	add esp,4 ;pop ...
3469
 
3470
	fadd st0,st0 ; len*=2
3471
	ftst
3472
	fstsw ax
3473
 
3474
	fld1
3475
	sahf
3476
	jle @f ;избегаем деления на 0
3477
		fdiv st0,st1
3478
	@@:
3479
	fstp dword[delt_t]
3480
 
5389 IgorA 3481
	ffree st0 ;1.0
3482
	fincstp
1535 IgorA 3483
 
3484
	;fild word[coord_p2+2] ;y2
3485
	fild word[coord_p1+2] ;y1
3486
	fild word[coord_p0+2] ;y0
3487
	fild word[coord_p2] ;x2
3488
	fild word[coord_p1] ;x1
3489
	fild word[coord_p0] ;x0
3490
	fld dword[delt_t]
3491
	fldz ;t=.0
3492
 
3493
	@@:
3494
		fld1
3495
		fsub st0,st1 ;1.-t
3496
		fmul st0,st0 ;pow(1.-t,2)
3497
		fmul st0,st3 ;...*x0
3498
		fstp dword[opr_param]
3499
 
3500
		fld1
3501
		fsub st0,st1 ;1.-t
3502
		fmul st0,st1 ;(1.-t)*t
3503
		fadd st0,st0
3504
		fmul st0,st4 ;...*x1
3505
		mov esi,dword[opr_param]
3506
		fstp dword[opr_param]
3507
 
5389 IgorA 3508
		fld st0 ;st0=t
3509
		fmul st0,st0 ;t^2
3510
		fmul st0,st5 ;(t^2)*x2
1535 IgorA 3511
 
3512
		fadd dword[opr_param]
3513
		mov dword[opr_param],esi
3514
		fadd dword[opr_param]
3515
		fistp word[v_poi_0] ;x
3516
 
3517
		fld1
3518
		fsub st0,st1 ;1.-t
3519
		fmul st0,st0 ;pow(1.-t,2)
3520
		fmul st0,st6 ;...*y0
3521
		fstp dword[opr_param]
3522
 
3523
		fld1
3524
		fsub st0,st1 ;1.-t
3525
		fmul st0,st1 ;(1.-t)*t
3526
		fadd st0,st0
3527
		fmul st0,st7 ;...*y1
3528
		mov esi,dword[opr_param]
3529
		fstp dword[opr_param]
3530
 
5389 IgorA 3531
		fld st0 ;st0=t
3532
		fmul st0,st0 ;t^2
3533
		fimul word[coord_p2+2] ;(t^2)*y2
1535 IgorA 3534
 
3535
		fadd dword[opr_param]
3536
		mov dword[opr_param],esi
3537
		fadd dword[opr_param]
3538
		fistp word[v_poi_0+2] ;y
3539
 
3540
		mov eax,1
3541
		mov bx,word[v_poi_0+2]
3542
		mov cx,word[v_poi_0]
3543
		call draw_pixel
3544
 
3545
		fadd st0,st1 ;t+dt
3546
 
3547
		fld1
3548
		fcomp
3549
		fstsw ax
3550
		sahf
3551
	jae @b
3552
 
3553
	popad
3554
	ret
3555
endp
3556
 
3138 heavyiron 3557
;фильтр
3105 IgorA 3558
align 4
3559
proc buf_filter_dither, buffer:dword, algor:dword
3560
	pushad
3561
	mov edi,[buffer]
3562
	cmp buf2d_bits,24
3563
	jne .error
3564
		mov edx,buf2d_w
3565
		mov esi,buf2d_h
3566
		mov edi,buf2d_data
3567
;edi - pointer to 24bit bitmap
3568
;edx - x size
3569
;esi - y size
3138 heavyiron 3570
		lea   edx,[edx+edx*2]
3105 IgorA 3571
		imul  esi,edx
2748 IgorA 3572
 
3105 IgorA 3573
		;определяем какой алгоритм использовать
3574
		cmp dword[algor],0
3575
		jne @f
3576
			call dither_0
3577
			jmp .dither_end
3578
		@@:
3579
		cmp dword[algor],1
3580
		jne @f
3581
			call dither_1
3582
			jmp .dither_end
3583
		@@:
3138 heavyiron 3584
		cmp dword[algor],2
3585
		jne @f
3586
			call dither_2
3587
			jmp .dither_end
3588
		@@:
3589
		cmp dword[algor],3
3590
		jne @f
3591
			call dither_3
3592
			jmp .dither_end
3593
		@@:
3594
		call dither_4
3105 IgorA 3595
		jmp .dither_end
3596
	.error:
3597
		stdcall print_err,sz_buf2d_filter_dither,txt_err_n24b
3598
	.dither_end:
3599
	popad
3600
	ret
3601
endp
2748 IgorA 3602
 
3105 IgorA 3603
align 16
3138 heavyiron 3604
dither_0: ; Sierra Filter Lite algorithm
3105 IgorA 3605
newp_0:   ; Dithering cycle
3606
	xor   ebx,ebx ; At first threshold
3607
	movzx ecx,byte[edi]
3608
	cmp   cl,255
3609
	je    newp_0.next
3610
	test  cl,cl
3611
	jz    newp_0.next
3612
	jns   @f
3613
	dec   ebx
3614
	sub   ecx,255
3615
@@:
3616
	mov   [edi],bl               ; putpixel
3617
 
3618
	sar   ecx,1                  ; error/2
3619
	;adc   ecx,0                  ; round to integer
3620
 
3621
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3622
	add   eax,ecx                ; add error/2 to (x+1;y)
3623
	jge   @f                     ; check_overflow
3624
	xor   eax,eax
3625
	jmp   .ok
3626
@@:
3627
	cmp   eax,255
3628
	jle   .ok
3629
	or    al,255
3630
.ok:
3631
	mov   [edi+3],al             ; putpixel
3632
 
3633
	sar   ecx,1                  ; error/4
3634
	adc   ecx,0                  ; round to integer
3635
 
3636
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3637
	add   eax,ecx                ; add error/4 to (x-1;y+1)
3638
	jge   @f                     ; check_overflow
3639
	xor   eax,eax
3640
	jmp   .ok1
3641
@@:
3642
	cmp   eax,255
3643
	jle   .ok1
3644
	or    al,255
3645
.ok1:
3646
	mov   [edi+edx-3],al         ; putpixel
3647
 
3648
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3649
	add   eax,ecx                ; add error/4 to (x;y+1)
3650
	jge   @f                     ; check_overflow
3651
	xor   eax,eax
3652
	jmp   .ok2
3653
@@:
3654
	cmp   eax,255
3655
	jle   .ok2
3656
	or    al,255
3657
.ok2:
3658
	mov   [edi+edx],al           ; putpixel
3659
 
3660
.next:
3661
	inc   edi
3662
	dec   esi
3663
	jnz   newp_0
3664
	ret
3665
 
3666
align 16
3138 heavyiron 3667
dither_1: ; Floyd-Steinberg algorithm
3105 IgorA 3668
newp_1:   ; Dithering cycle
3669
	xor   ebx,ebx ; At first threshold
3670
	movzx ecx,byte[edi]
3671
	cmp   cl,255
3672
	je    newp_1.next
3673
	test  cl,cl
3674
	jz    newp_1.next
3675
	jns   @f
3676
	dec   ebx
3677
	sub   ecx,255
3678
@@:
3679
	mov   [edi],bl               ; putpixel
3680
 
3681
	sar   ecx,4                  ; error/16
3682
	adc   ecx,0                  ; round to integer
3683
	mov   ebx,ecx
3684
 
3685
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3686
	add   eax,ecx                ; add error/16 to (x+1;y+1)
3687
	jge   @f                     ; check_overflow
3688
	xor   eax,eax
3689
	jmp   .ok
3690
@@:
3691
	cmp   eax,255
3692
	jle   .ok
3693
	or    al,255
3694
.ok:
3695
	mov   [edi+edx+3],al         ;putpixel
3696
 
3697
	imul  ecx,3
3698
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3699
	add   eax,ecx                ; add 3*error/16 to (x-1;y+1)
3700
	jge   @f                     ; check_overflow
3701
	xor   eax,eax
3702
	jmp   .ok1
3703
@@:
3704
	cmp   eax,255
3705
	jle   .ok1
3706
	or    al,255
3707
.ok1:
3708
	mov   [edi+edx-3],al         ;putpixel
3709
 
3710
	mov   ecx,ebx
3711
	imul  ecx,5
3712
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3713
	add   eax,ecx                ; add 5*error/16 to (x;y+1)
3714
	jge   @f                     ; check_overflow
3715
	xor   eax,eax
3716
	jmp   .ok2
3717
@@:
3718
	cmp   eax,255
3719
	jle   .ok2
3720
	or    al,255
3721
.ok2:
3722
	mov   [edi+edx],al           ;putpixel
3723
 
3724
	mov   ecx,ebx
3725
	imul  ecx,7
3726
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3727
	add   eax,ecx                ; add 7*error/16 to (x+1;y)
3728
	jge   @f                     ; check_overflow
3729
	xor   eax,eax
3730
	jmp   .ok3
3731
@@:
3732
	cmp   eax,255
3733
	jle   .ok3
3734
	or    al,255
3735
.ok3:
3736
	mov   [edi+3],al             ;putpixel
3737
 
3738
.next:
3739
	inc  edi
3740
	dec  esi
3741
	jnz  newp_1
3742
	ret
3743
 
3744
align 16
3138 heavyiron 3745
dither_2: ; Burkes algorithm
3105 IgorA 3746
newp_2:   ; Dithering cycle
3747
	xor   ebx,ebx ; At first threshold
3748
	movsx ecx,byte[edi]
3749
	cmp   cl,255
3750
	je    newp_2.next
3751
	test  cl,cl
3752
	jz    newp_2.next
3753
	jns   @f
3754
	dec   ebx
3755
@@:
3756
	mov   [edi],bl               ; putpixel
3757
 
3758
	sar   ecx,2                  ; error/4
3759
	adc   ecx,0                  ; round to integer
3760
 
3761
	movzx eax,byte[edi+3]        ; pixel (x+1;y)
3762
	add   eax,ecx                ; add error/4 to (x+1;y)
3763
	jge   @f                     ; check_overflow
3764
	xor   eax,eax
3765
	jmp   .ok
3766
@@:
3767
	cmp   eax,255
3768
	jle   .ok
3769
	or    al,255
3770
.ok:
3771
	mov   [edi+3],al             ; putpixel
3772
 
3773
	movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3774
	add   eax,ecx                ; add error/4 to (x;y+1)
3775
	jge   @f                     ; check_overflow
3776
	xor   eax,eax
3777
	jmp   .ok1
3778
@@:
3779
	cmp   eax,255
3780
	jle   .ok1
3781
	or    al,255
3782
.ok1:
3783
	mov   [edi+edx],al           ; putpixel
3784
 
3785
	sar   ecx,1                  ; error/8
3786
	adc   ecx,0                  ; round to integer
3787
 
3788
	movzx eax,byte[edi+6]        ; pixel (x+2;y)
3789
	add   eax,ecx                ; add error/8 to (x+2;y)
3790
	jge   @f                     ; check_overflow
3791
	xor   eax,eax
3792
	jmp   .ok2
3793
@@:
3794
	cmp   eax,255
3795
	jle   .ok2
3796
	or    al,255
3797
.ok2:
3798
	mov   [edi+6],al             ; putpixel
3799
 
3800
	movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3801
	add   eax,ecx                ; add error/8 to (x-1;y+1)
3802
	jge   @f                     ; check_overflow
3803
	xor   eax,eax
3804
	jmp   .ok3
3805
@@:
3806
	cmp   eax,255
3807
	jle   .ok3
3808
	or    al,255
3809
.ok3:
3810
	mov   [edi+edx-3],al         ; putpixel
3811
 
3812
	movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3813
	add   eax,ecx                ; add error/8 to (x+1;y+1)
3814
	jge   @f                     ; check_overflow
3815
	xor   eax,eax
3816
	jmp   .ok4
3817
@@:
3818
	cmp   eax,255
3819
	jle   .ok4
3820
	or    al,255
3821
.ok4:
3822
	mov   [edi+edx+3],al         ; putpixel
3823
 
3824
	sar   ecx,1                  ; error/16
3825
	;adc   ecx,0                  ; round to integer
3826
 
3827
	movzx eax,byte[edi+edx-6]    ; pixel (x-2;y+1)
3828
	add   eax,ecx                ; add error/16 to (x-2;y+1)
3829
	jge   @f                     ; check_overflow
3830
	xor   eax,eax
3831
	jmp   .ok5
3832
@@:
3833
	cmp   eax,255
3834
	jle   .ok5
3835
	or    al,255
3836
.ok5:
3837
	mov   [edi+edx-6],al         ; putpixel
3838
 
3839
	movzx eax,byte[edi+edx+6]    ; pixel (x+2;y+1)
3840
	add   eax,ecx                ; add error/16 to (x+2;y+1)
3841
	jge   @f                     ; check_overflow
3842
	xor   eax,eax
3843
	jmp   .ok6
3844
@@:
3845
	cmp   eax,255
3846
	jle   .ok6
3847
	or    al,255
3848
.ok6:
3849
	mov   [edi+edx+6],al         ; putpixel
3850
 
3851
.next:
3852
	inc   edi
3853
	dec   esi
3854
	jnz   newp_2
3855
	ret
3856
 
3857
 
3138 heavyiron 3858
align 16
3859
dither_3:                        ; Heavyiron_mod algorithm
3860
 newp_3:                         ; Dithering cycle
3861
    xor   ebx,ebx                ; At first threshold
3862
    movzx ecx,byte[edi]
3863
    cmp   cl,255
3864
    je   .next
3865
    test  cl,cl
3866
    jz    .next
3867
    jns   @f
3868
    dec   ebx
3869
    sub   ecx,255
3870
  @@:
3871
    mov   [edi],bl               ; putpixel
3105 IgorA 3872
 
3138 heavyiron 3873
    sar   ecx,2                  ; error/4
3874
 
3875
    movzx eax,byte[edi+3]        ; pixel (x+1;y)
3876
    add   eax,ecx                ; add error/4 to (x+1;y)
3877
    jge   @f                     ; check_overflow
3878
    xor   eax,eax
3879
    jmp   .ok
3880
  @@:
3881
    cmp   eax,255
3882
    jle   .ok
3883
    or    al,255
3884
  .ok:
3885
    mov   [edi+3],al             ; putpixel
3886
 
3887
    movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3888
    add   eax,ecx                ; add error/4 to (x-1;y+1)
3889
    jge   @f                     ; check_overflow
3890
    xor   eax,eax
3891
    jmp   .ok1
3892
  @@:
3893
    cmp   eax,255
3894
    jle   .ok1
3895
    or    al,255
3896
  .ok1:
3897
    mov   [edi+edx-3],al         ; putpixel
3898
 
3899
    movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3900
    add   eax,ecx                ; add error/4 to (x;y+1)
3901
    jge   @f                     ; check_overflow
3902
    xor   eax,eax
3903
    jmp   .ok2
3904
  @@:
3905
    cmp   eax,255
3906
    jle   .ok2
3907
    or    al,255
3908
  .ok2:
3909
    mov   [edi+edx],al           ; putpixel
3910
 
3911
  .next:
3912
    inc   edi
3913
    dec   esi
3914
    jnz   newp_3
3915
    ret
3916
 
3917
align 16
3918
dither_4:                        ; Atkinson algorithm
3919
 newp_4:                         ; Dithering cycle
3920
 
3921
    xor   ebx,ebx                ; At first threshold
3922
    movsx ecx,byte[edi]
3923
    cmp   cl,255
3924
    je   .next
3925
    test  cl,cl
3926
    jz    .next
3927
    jns   @f
3928
    dec   ebx
3929
  @@:
3930
    mov   [edi],bl               ; putpixel
3931
 
3932
    sar   ecx,3                  ; error/8
3933
 
3934
    movzx eax,byte[edi+3]        ; pixel (x+1;y)
3935
    add   eax,ecx                ; add error/8 to (x+1;y)
3936
    jge   @f                     ; check_overflow
3937
    xor   eax,eax
3938
    jmp   .ok
3939
  @@:
3940
    cmp   eax,255
3941
    jle   .ok
3942
    or    al,255
3943
  .ok:
3944
    mov   [edi+3],al             ; putpixel
3945
 
3946
    movzx eax,byte[edi+edx]      ; pixel (x;y+1)
3947
    add   eax,ecx                ; add error/8 to (x;y+1)
3948
    jge   @f                     ; check_overflow
3949
    xor   eax,eax
3950
    jmp   .ok1
3951
  @@:
3952
    cmp   eax,255
3953
    jle   .ok1
3954
    or    al,255
3955
  .ok1:
3956
    mov   [edi+edx],al           ; putpixel
3957
 
3958
    movzx eax,byte[edi+6]        ; pixel (x+2;y)
3959
    add   eax,ecx                ; add error/8 to (x+2;y)
3960
    jge   @f                     ; check_overflow
3961
    xor   eax,eax
3962
    jmp   .ok2
3963
  @@:
3964
    cmp   eax,255
3965
    jle   .ok2
3966
    or    al,255
3967
  .ok2:
3968
    mov   [edi+6],al             ; putpixel
3969
 
3970
    movzx eax,byte[edi+edx-3]    ; pixel (x-1;y+1)
3971
    add   eax,ecx                ; add error/8 to (x-1;y+1)
3972
    jge   @f                     ; check_overflow
3973
    xor   eax,eax
3974
    jmp   .ok3
3975
  @@:
3976
    cmp   eax,255
3977
    jle   .ok3
3978
    or    al,255
3979
  .ok3:
3980
    mov   [edi+edx-3],al         ; putpixel
3981
 
3982
    movzx eax,byte[edi+edx+3]    ; pixel (x+1;y+1)
3983
    add   eax,ecx                ; add error/8 to (x+1;y+1)
3984
    jge   @f                     ; check_overflow
3985
    xor   eax,eax
3986
    jmp   .ok4
3987
  @@:
3988
    cmp   eax,255
3989
    jle   .ok4
3990
    or    al,255
3991
  .ok4:
3992
    mov   [edi+edx+3],al         ; putpixel
3993
 
3994
 
3995
    movzx eax,byte[edi+edx+edx]    ; pixel (x;y+2)
3996
    add   eax,ecx                ; add error/8 to (x;y+2)
3997
    jge   @f                     ; check_overflow
3998
    xor   eax,eax
3999
    jmp   .ok5
4000
  @@:
4001
    cmp   eax,255
4002
    jle   .ok5
4003
    or    al,255
4004
  .ok5:
4005
    mov   [edi+edx+edx],al         ; putpixel
4006
 
4007
  .next:
4008
    inc   edi
4009
    dec   esi
4010
    jnz   newp_4
4011
    ret
4012
 
4013
 
2748 IgorA 4014
;*** функции для работы с воксельной графикой ***
4015
 
4016
 
4017
 
4018
;создание воксельных кистей
4019
align 4
4020
proc vox_brush_create uses eax ebx ecx edi, h_br:dword, buf_z:dword
4021
	mov edi,[h_br]
4022
	movzx ecx,byte[edi+3]
4023
	add edi,4
4024
 
4025
	; *** создание единичной кисти ***
4026
	mov eax,[buf_z]
4027
	mov buf2d_data,eax
4028
	movzx eax,byte[edi-4] ;ширина единичной кисти
4029
	mov buf2d_w,eax ;ширина буфера
4030
	movzx eax,byte[edi-4+1] ;высота единичной кисти
4031
	mov buf2d_h,eax ;высота буфера
4032
	mov buf2d_size_lt,0 ;отступ слева и справа для буфера
4033
	mov buf2d_color,0 ;цвет фона буфера
4034
	mov buf2d_bits,32 ;количество бит в 1-й точке изображения
4035
 
4036
	; *** создание следующих кистей ***
4037
	cmp ecx,1
4038
	jl .end_creat
4039
	movzx ebx,byte[edi-4+2] ;высота основания единичной кисти
4040
	shr ebx,1
4041
	cld
4042
	@@:
4043
		mov eax,edi
4044
		add edi,BUF_STRUCT_SIZE
4045
		stdcall vox_create_next_brush, eax, edi, ebx
4046
		shl ebx,1
4047
		loop @b
4048
	.end_creat:
4049
	ret
4050
endp
4051
 
4052
;удаление воксельных кистей
4053
align 4
4054
proc vox_brush_delete uses ecx edi, h_br:dword
4055
	mov edi,[h_br]
4056
	movzx ecx,byte[edi+3]
4057
	add edi,4
4058
 
4059
	; *** удаление кистей ***
4060
	cmp ecx,1
4061
	jl .end_delete
4062
	cld
4063
	@@:
4064
		add edi,BUF_STRUCT_SIZE
4065
		stdcall buf_delete, edi
4066
		loop @b
4067
	.end_delete:
4068
	ret
4069
endp
4070
 
4071
;функция для создания вокселя следующего порядка
4072
; buf_v1 - буфер с исходным вокселем
4073
; buf_v2 - буфер с увеличеным вокселем
4074
; h - высота основания исходного вокселя : 2
4075
align 4
4076
proc vox_create_next_brush uses eax ebx ecx edx edi, buf_v1:dword, buf_v2:dword, h:dword
4077
	mov edi,[buf_v1]
4078
	mov ebx,buf2d_h
4079
	mov ecx,buf2d_w
4080
	mov edi,[buf_v2]
4081
	mov buf2d_h,ebx
4082
	shl buf2d_h,1
4083
	mov buf2d_w,ecx
4084
	shl buf2d_w,1
4085
	mov buf2d_color,0
4086
	mov buf2d_bits,32
4087
 
4088
	stdcall buf_create, [buf_v2] ;создание буфера глубины
4089
	shr ecx,1
4090
	mov edx,[h]
4091
	shl edx,1
4092
	sub ebx,edx
4093
	;ecx - ширина исходного вокселя : 2
4094
	;ebx - высота исходного вокселя (без основания)
4095
	;edx - высота основания исходного вокселя
4096
	mov eax,[h]
2975 IgorA 4097
	cmp eax,0
4098
	je @f
4099
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,0
4100
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,0
2748 IgorA 4101
 
2975 IgorA 4102
		stdcall vox_add, [buf_v2], [buf_v1], 0,eax,eax
4103
		push eax ;stdcall ...
4104
		add eax,ebx
4105
		stdcall vox_add, [buf_v2], [buf_v1], 0,eax ;,...
4106
		sub eax,ebx
4107
		shl ecx,1
2748 IgorA 4108
 
2975 IgorA 4109
		;ecx - ширина исходного вокселя
4110
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax,eax
4111
		push eax ;stdcall ...,[h]
4112
		add eax,ebx
4113
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax;,[h]
4114
		;sub eax,ebx
4115
		shr ecx,1
2748 IgorA 4116
 
2975 IgorA 4117
		;ecx - ширина исходного вокселя : 2
4118
		stdcall vox_add, [buf_v2], [buf_v1], ecx,edx,edx
4119
		add ebx,edx
4120
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,edx
4121
 
4122
		jmp .end_0
4123
	@@:
4124
		;если h = 0, тогда получаем кисть на 2 грани
4125
		;в таком случае для получения глубины берем ширину / 2
4126
		mov eax,ecx
4127
		;2 левых вокселя
4128
		stdcall vox_add, [buf_v2], [buf_v1], 0,0,eax
4129
		stdcall vox_add, [buf_v2], [buf_v1], 0,ebx,eax
4130
		shl eax,1
4131
		;2 центральных передних вокселя (задние центральные не выводим)
4132
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
4133
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax
4134
		shr eax,1
4135
		shl ecx,1
4136
		;2 правых вокселя
4137
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
4138
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax
4139
 
4140
	.end_0:
4141
 
4142
 
2748 IgorA 4143
	ret
4144
endp
4145
 
4146
;
4147
align 4
2758 IgorA 4148
proc vox_add, buf_v1:dword, buf_v2:dword, coord_x:dword, coord_y:dword, coord_z:dword
2748 IgorA 4149
pushad
2759 IgorA 4150
	mov ebx,[coord_x]
4151
	mov eax,[coord_y]
2748 IgorA 4152
	mov edi,[buf_v2]
4153
	mov ecx,buf2d_h
4154
	mov esi,buf2d_w
4155
	imul ecx,esi
2759 IgorA 4156
	add esi,ebx
2748 IgorA 4157
	mov edx,buf2d_data
4158
	cld
4159
	;ecx - count pixels in voxel
4160
	;edx - указатель на данные в воксельном буфере
4161
	;edi - указатель на воксельный буфер
4162
	;esi - width voxel buffer add coord x
4163
	.cycle:
4164
		cmp dword[edx],0
4165
		je @f
4166
			;проверяем буфер глубины
2759 IgorA 4167
			push eax ecx edi esi
2748 IgorA 4168
			mov ecx,eax
2759 IgorA 4169
			mov edi,[buf_v1]
4170
			call get_pixel_32 ;stdcall buf_get_pixel, [buf_v1],ebx,ecx
2748 IgorA 4171
			mov esi,[edx]
4172
			add esi,[coord_z]
4173
			cmp eax,esi
4174
			jge .end_draw
2759 IgorA 4175
			stdcall buf_set_pixel, [buf_v1],ebx,ecx,esi ;esi = new coord z
2748 IgorA 4176
			.end_draw:
2759 IgorA 4177
			pop esi edi ecx eax
2748 IgorA 4178
		@@:
4179
		add edx,4
2759 IgorA 4180
		inc ebx
4181
		cmp ebx,esi
2748 IgorA 4182
		jl @f
2759 IgorA 4183
			inc eax
4184
			sub ebx,buf2d_w
2748 IgorA 4185
		@@:
4186
		loop .cycle
4187
popad
4188
	ret
4189
endp
4190
 
2758 IgorA 4191
;description:
4192
; возврашает ширину воксельного изображения с 3-мя гранями
4193
; принимает указатель на кисть и масштаб
4194
align 4
4195
proc buf_vox_obj_get_img_w_3g uses ecx, h_br:dword,k_scale:dword
4196
	mov ecx,[h_br]
4197
 
4198
	movzx eax,byte[ecx]
4199
	cmp dword[k_scale],1
4200
	jl .end_c0
4201
		mov ecx,[k_scale]
4202
		shl eax,cl
4203
	.end_c0:
4204
	ret
4205
endp
4206
 
4207
;description:
4208
; возврашает высоту воксельного изображения с 3-мя гранями
4209
; принимает указатель на кисть и масштаб
4210
align 4
4211
proc buf_vox_obj_get_img_h_3g uses ecx, h_br:dword,k_scale:dword
4212
	mov ecx,[h_br]
4213
 
4214
	movzx eax,byte[ecx+1]
4215
	cmp dword[k_scale],1
4216
	jl .end_c0
4217
		mov ecx,[k_scale]
4218
		shl eax,cl
4219
	.end_c0:
4220
	ret
4221
endp
4222
 
4223
;description:
2815 IgorA 4224
; функция рисующая воксельный объект (видна 1 грань)
2758 IgorA 4225
;input:
4226
; buf_i - буфер в котором рисуется (24 бита)
4227
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2815 IgorA 4228
align 4
4229
proc buf_vox_obj_draw_1g, buf_i:dword, buf_z:dword, v_obj:dword, coord_x:dword,\
4230
coord_y:dword, k_scale:dword
4231
	cmp [k_scale],0
4232
	jl .end_f
4233
pushad
4234
	mov edi,[buf_i]
4235
	cmp buf2d_bits,24
4236
	jne .error1
4237
	mov edi,[buf_z]
4238
	cmp buf2d_bits,32
4239
	jne .error2
4240
 
4241
	mov ecx,[k_scale]
4242
	mov ebx,[coord_x]
4243
	mov edx,[coord_y]
4244
	mov edi,[v_obj]
4245
	add edi,vox_offs_data
4246
	xor esi,esi
4247
	stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
4248
 
4249
	jmp .end_0
4250
	.error1:
4251
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n24b
4252
		jmp .end_0
4253
	.error2:
4254
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n32b
4255
	.end_0:
4256
popad
4257
	.end_f:
4258
	ret
4259
endp
4260
 
4261
;input:
4262
; ebx - coord_x
4263
; edx - coord_y
4264
; esi - coord_z
4265
; ecx - уровень текушего узла
4266
; edi - указатель на данные воксельного объекта
4267
align 4
4268
proc draw_sub_vox_obj_1g, buf_i:dword, buf_z:dword, v_obj:dword
4269
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4270
	je .sub_trees
4271
 
4272
		;прорисовка рамки если размер узла = 1
4273
		cmp ecx,0
4274
		jne @f
4275
			;проверка глубины esi
4276
			stdcall buf_get_pixel, [buf_z], ebx,edx, esi
4277
			cmp eax,esi
4278
			jge @f
4279
				push ecx
4280
				mov ecx,dword[edi]
4281
				and ecx,0xffffff
4282
				stdcall buf_set_pixel, [buf_i], ebx,edx, ecx
4283
				stdcall buf_set_pixel, [buf_z], ebx,edx, esi
4284
				pop ecx
4285
		@@:
4286
 
4287
		;рекурсивный перебор поддеревьев
4288
		push edx
4289
		;вход внутрь узла
4290
		dec ecx
4291
 
4292
		mov eax,1
4293
		cmp ecx,1
4294
		jl @f
4295
			shl eax,cl
4296
		@@:
4297
 
4298
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4299
 
4300
		mov ah,byte[edi+3]
4301
		add edi,4
4302
		mov al,8
4303
		.cycle:
4304
			bt ax,8 ;тестируем только ah
4305
			jnc .c_next
4306
				push eax ebx edx esi
4307
				stdcall vox_corect_coords_pl, [v_obj],1
4308
				stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
4309
				pop esi edx ebx eax
4310
			.c_next:
4311
			shr ah,1
4312
			dec al
4313
			jnz .cycle
4314
		;выход из узла
4315
		inc ecx
4316
		pop edx
4317
		jmp .end_f
4318
	.sub_trees:
4319
		cmp ecx,0
4320
		jl .end_0 ;не рисуем очень маленькие воксели
4321
 
4322
			;рисуем узел
4323
			mov eax,[edi]
4324
			and eax,0xffffff
4325
 
4326
			cmp ecx,1
4327
			jl @f
4328
				;квадрат больше текущего масштаба
4329
				stdcall vox_draw_square_1g, [buf_i],[buf_z],eax
4330
				jmp .end_0
4331
			@@:
4332
				;квадрат текущего масштаба
4333
				push ecx
4334
				mov ecx,eax
4335
				stdcall buf_get_pixel, [buf_z], ebx,edx
4336
				cmp eax,esi
4337
				jge .end_1
4338
				stdcall buf_set_pixel, [buf_i], ebx,edx,ecx
4339
				stdcall buf_set_pixel, [buf_z], ebx,edx,esi
4340
				.end_1:
4341
				pop ecx
4342
		.end_0:
4343
		add edi,4
4344
	.end_f:
4345
	ret
4346
endp
4347
 
4348
;output:
4349
; eax - разрушается
4350
align 4
4351
proc vox_draw_square_1g uses ecx edx edi, buf_i:dword, buf_z:dword, color:dword
4352
locals
4353
	img_size dd ?
4354
	coord_y dd ?
4355
endl
4356
	mov edi,[buf_z]
4357
	xor eax,eax
4358
	inc eax
4359
	shl eax,cl
4360
	mov [img_size],eax
4361
	mov [coord_y],eax
4362
	.cycle_0:
4363
	push ebx
4364
	mov ecx,[img_size]
4365
	cld
4366
	.cycle_1:
4367
		push ecx
4368
		mov ecx,edx
4369
		call get_pixel_32
4370
		pop ecx
4371
		cmp eax,esi
4372
		jge @f
4373
			stdcall buf_set_pixel, [buf_i], ebx,edx, [color]
4374
			stdcall buf_set_pixel, edi, ebx,edx, esi
4375
		@@:
4376
		inc ebx
4377
	loop .cycle_1
4378
	pop ebx
4379
	inc edx
4380
	dec dword[coord_y]
4381
	jnz .cycle_0
4382
	ret
4383
endp
4384
 
4385
;description:
4386
; функция рисующая воксельный объект (видно 3 грани)
4387
;input:
4388
; buf_i - буфер в котором рисуется (24 бита)
4389
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
2758 IgorA 4390
; h_br - кисть с изображениями вокселей (32 бита)
4391
; v_obj - воксельный объект
4392
; k_scale - коэф. для масштабирования изображения
4393
align 4
4394
proc buf_vox_obj_draw_3g, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
4395
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword
4396
pushad
4397
	mov edi,[v_obj]
4398
	mov ecx,[k_scale]
4399
	mov ebx,[coord_x]
4400
	mov edx,[coord_y]
4401
	add edi,vox_offs_data
4402
	mov esi,[coord_z]
4403
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4404
popad
4405
	ret
4406
endp
4407
 
4408
;description:
4409
; функция рисующая часть воксельного объекта
4410
;input:
4411
; buf_i - буфер в котором рисуется (24 бита)
4412
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
4413
; h_br - кисть с изображениями вокселей (32 бита)
4414
; v_obj - воксельный объект
4415
; k_scale - коэф. для масштабирования изображения
4416
align 4
4417
proc buf_vox_obj_draw_3g_scaled, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
4418
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword,\
4419
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword,b_color:dword
4420
pushad
4421
locals
4422
	p_node dd 0 ;родительский узел
4423
endl
4424
	mov edi,[v_obj]
4425
	add edi,vox_offs_data
4426
 
4427
	mov ecx,[k_scale]
4428
	mov ebx,[coord_x]
4429
 
4430
	;тестовая рамка
4431
	mov eax,[h_br]
4432
 
4433
	movzx edx,byte[eax]
4434
	movzx esi,byte[eax+1]
4435
	cmp ecx,1
4436
	jl .end_c0
4437
		shl edx,cl
4438
		shl esi,cl
4439
	.end_c0:
4440
	;stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
4441
 
4442
	;вертикальная полоса
4443
	add ebx,edx
4444
	shr edx,cl
4445
	stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
4446
	mov ecx,[s_k_scale]
4447
	shr esi,cl
4448
	xor eax,eax
4449
	inc eax
4450
	shl eax,cl
4451
	dec eax
4452
	sub eax,[s_c_z] ;значения по оси z возрастают с низу вверх
4453
	imul eax,esi
4454
	add eax,[coord_y]
4455
	stdcall buf_filled_rect_by_size, [buf_i], ebx,eax,edx,esi, [b_color]
4456
	mov ebx,[coord_y]
4457
	shl esi,cl
4458
	add ebx,esi
4459
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
4460
	shr eax,1
4461
	mov esi,[h_br]
4462
	movzx esi,byte[esi+1]
4463
	;ползунок
4464
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,eax,esi, [s_c_x], [s_k_scale], [b_color]
4465
	mov edx,[coord_x]
4466
	add edx,eax
4467
	;ползунок
4468
	stdcall draw_polz_hor, [buf_i], edx,ebx,eax,esi, [s_c_y], [s_k_scale], [b_color]
4469
;---
4470
 
4471
	mov esi,[s_k_scale]
4472
	cmp esi,1
4473
	jl .end_2
4474
 
4475
	; *** (1) ***
4476
	.found:
4477
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
4478
	movzx bx,byte[edi+3]
4479
	mov [p_node],edi
4480
	add edi,4
4481
	cmp eax,0
4482
	je .end_1
4483
	mov ecx,eax
4484
	cld
4485
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
4486
		bt bx,0 ;проверяем есть ли дочерние узлы
4487
		jnc .end_0
4488
			xor eax,eax
4489
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
4490
		.end_0:
4491
		shr bx,1
4492
		loop @b
4493
	.end_1:
4494
	bt bx,0
4495
	jnc .end_2 ;если поддерева не существует
4496
	dec esi
4497
	cmp esi,0
4498
	jg .found
4499
 
4500
	; *** (2) ***
4501
	;рисование части объекта
4502
	mov ecx,[k_scale]
4503
	mov ebx,[coord_x]
4504
	mov edx,[coord_y]
4505
	mov esi,[coord_z]
4506
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4507
	.end_2:
4508
 
4509
popad
4510
	ret
4511
endp
4512
 
4513
;input:
4514
; h_br - кисть с изображениями вокселей (32 бита)
4515
; ebx - coord_x
4516
; edx - coord_y
4517
; esi - coord_z
4518
; ecx - уровень текушего узла
4519
; edi - указатель на данные воксельного объекта
4520
align 4
4521
proc vox_go_in_node, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword
4522
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
4523
	je .sub_trees
4524
		;рекурсивный перебор поддеревьев
4525
		push eax edx
4526
 
4527
		;прорисовка рамки если размер узла = 1
4528
		cmp ecx,0
4529
		jne .end_2
4530
			push eax
4531
				stdcall vox_get_sub_brush,[h_br],0 ;определяем кисть для рисования
4532
				cmp eax,0 ;если кисть не найдена
4533
				je @f
4534
					stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
4535
				@@:
4536
			pop eax
4537
		.end_2:
4538
 
4539
		;вход внутрь узла
4540
		dec ecx
4541
;---
4542
		push ebx
4543
			;mov eax,(h-h_osn/2)
4544
			mov ebx,[h_br]
4545
			movzx eax,byte[ebx+1]
2975 IgorA 4546
			cmp byte[ebx+2],0
4547
			je @f
4548
				;если кисть с 3-мя гранями
4549
				movzx ebx,byte[ebx+2]
4550
				shr ebx,1
4551
				sub eax,ebx
4552
				jmp .end_0
4553
			@@:
4554
				;если кисть с 2-мя гранями
4555
				movzx ebx,byte[ebx]
4556
				shr ebx,1
4557
			.end_0:
2758 IgorA 4558
		cmp ecx,1
2975 IgorA 4559
		jl @f
2758 IgorA 4560
			shl eax,cl
4561
			shl ebx,cl
2975 IgorA 4562
		@@:
2758 IgorA 4563
		add esi,ebx
4564
		pop ebx
4565
		add edx,eax ;коректировка высоты под воксель нижнего уровня
4566
;---
4567
		mov ah,byte[edi+3]
4568
		add edi,4
4569
		mov al,8
4570
		.cycle:
4571
			bt ax,8 ;тестируем только ah
4572
			jnc .c_next
4573
				push ebx edx esi
4574
				stdcall vox_corect_coords, [h_br], [v_obj]
4575
				stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
4576
				pop esi edx ebx
4577
			.c_next:
4578
			shr ah,1
4579
			dec al
4580
			jnz .cycle
4581
 
4582
		;выход из узла
4583
		inc ecx
4584
		pop edx eax
4585
 
4586
		jmp .end_f
4587
	.sub_trees:
4588
		;рисуем узел
4589
		push eax
4590
			stdcall vox_get_sub_brush,[h_br],ecx ;определяем кисть для рисования
4591
			cmp eax,0 ;если кисть не найдена
4592
			je @f
4593
				stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
4594
			@@:
4595
		pop eax
4596
 
4597
		add edi,4
4598
	.end_f:
4599
	ret
4600
endp
4601
 
4602
;description:
4603
; функция рисующая одиночный воксел
4604
;input:
4605
; buf_i - буфер в котором рисуется (24 бита)
4606
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
4607
; buf_v - буфер с изображением вокселя (32 бита)
4608
; v_color - цвет
4609
align 4
4610
proc draw_vox, buf_i:dword, buf_z:dword, buf_v:dword,\
4611
coord_x:dword, coord_y:dword, coord_z:dword, v_color:dword
4612
pushad
4613
	mov eax,[coord_x]
4614
	mov ebx,[coord_y]
4615
	mov edi,[buf_v]
4616
	mov ecx,buf2d_h
4617
	mov esi,buf2d_w
4618
	imul ecx,esi
4619
	add esi,eax
4620
	mov edx,buf2d_data
4621
	cld
4622
	;ecx - count pixels in voxel
4623
	;edx - указатель на данные в воксельном буфере
4624
	;edi - указатель на воксельный буфер
4625
	;esi - width voxel buffer add coord x
4626
	.cycle:
4627
		cmp dword[edx],0
4628
		je @f
4629
			;проверяем буфер глубины
4630
			push eax
4631
			stdcall buf_get_pixel, [buf_z],eax,ebx
4632
			sub eax,[coord_z]
4633
			cmp eax,[edx]
4634
			jl .dr_pixel
4635
				pop eax
4636
				jmp @f
4637
			.dr_pixel:
4638
				;рисуем точку
4639
				pop eax
4640
				stdcall buf_set_pixel, [buf_i],eax,ebx,[v_color]
4641
				push ecx
4642
				mov ecx,[coord_z]
4643
				add ecx,[edx]
4644
				stdcall buf_set_pixel, [buf_z],eax,ebx,ecx
4645
				pop ecx
4646
		@@:
4647
		add edx,4
4648
		inc eax
4649
		cmp eax,esi
4650
		jl @f
4651
			inc ebx
4652
			sub eax,buf2d_w
4653
		@@:
4654
		loop .cycle
4655
popad
4656
	ret
4657
endp
4658
 
4659
;description:
4660
;функция для коректировки координат
4661
;направления осей координат в вокселе:
4662
;*z
4663
;|
4664
;+
4665
;  * y
4666
; /
4667
;+
4668
; \
4669
;  * x
4670
;input:
4671
;  al - номер узла в дереве (от 1 до 8)
4672
; ebx - координата x
4673
; edx - координата y
4674
; esi - координата z
4675
; ecx - уровень текушего узла
4676
;output:
4677
; ebx - новая координата x
4678
; edx - новая координата y
4679
; esi - новая координата z
4680
align 4
4681
proc vox_corect_coords, h_br:dword, v_obj:dword
4682
locals
4683
	osn_w_2 dd ? ;ширина основания единичного вокселя : 2
4684
	vox_h dd ? ;высота единичного вокселя
4685
endl
4686
	cmp ecx,0
4687
	jl .end_f ;для ускорения отрисовки
4688
 
4689
	push eax edi
4690
	and eax,15 ;выделяем номер узла в дереве
4691
	mov edi,[v_obj]
4692
	add edi,vox_offs_tree_table
4693
	add edi,8
4694
	sub edi,eax
4695
 
4696
	push ebx ecx
4697
		mov ebx,[h_br]
4698
 
4699
		movzx ecx,byte[ebx]
4700
		shr ecx,1
4701
		mov dword[osn_w_2],ecx
4702
 
4703
		movzx ecx,byte[ebx+2]
4704
		movzx ebx,byte[ebx+1]
4705
		sub ebx,ecx
4706
		mov dword[vox_h],ebx
4707
		shr ecx,1
4708
		mov eax,ecx ;eax - высота основания единичного вокселя : 2
4709
	pop ecx ebx
4710
 
4711
	cmp ecx,1
2975 IgorA 4712
	jl @f ;во избежание зацикливания
2758 IgorA 4713
		shl eax,cl
4714
		shl dword[osn_w_2],cl
4715
		shl dword[vox_h],cl
2975 IgorA 4716
	@@:
2758 IgorA 4717
 
4718
;	add esi,eax ;меняем глубину для буфера z (компенсация для координаты y)
4719
	bt word[edi],0 ;test voxel coord x
4720
	jnc @f
4721
		add ebx,[osn_w_2]
2975 IgorA 4722
		cmp eax,0
4723
		jne .end_0
4724
			add esi,[osn_w_2] ;меняем глубину для буфера z
4725
			jmp @f
4726
		.end_0:
2758 IgorA 4727
		add edx,eax
4728
		add esi,eax ;меняем глубину для буфера z
4729
	@@:
4730
	bt word[edi],1 ;test voxel coord y
4731
	jnc @f
4732
		add ebx,[osn_w_2]
2975 IgorA 4733
		cmp eax,0
4734
		jne .end_1
4735
			sub esi,[osn_w_2] ;меняем глубину для буфера z
4736
			jmp @f
4737
		.end_1:
2758 IgorA 4738
		sub edx,eax
4739
		sub esi,eax ;меняем глубину для буфера z
4740
	@@:
4741
	bt word[edi],2 ;test voxel coord z
4742
	jnc @f
4743
		sub edx,[vox_h]
4744
	@@:
4745
	pop edi eax
4746
	.end_f:
4747
	ret
4748
endp
4749
 
4750
;извлекаем из h_br указатель на буфер с изображением вокселя, указанного порядка n
4751
align 4
4752
proc vox_get_sub_brush uses ebx ecx, h_br:dword, n:dword
4753
	xor eax,eax
4754
	mov ebx,[n]
4755
	cmp ebx,0
4756
	jl @f
4757
	mov ecx,[h_br]
4758
	cmp bl,byte[ecx+3]
4759
	jg @f
4760
		add ecx,4
4761
		imul ebx,BUF_STRUCT_SIZE
4762
		mov eax,ebx
4763
		add eax,ecx
4764
	@@:
4765
	ret
4766
endp
4767
 
4768
;description:
4769
; функция рисующая срез воксельного обьекта
4770
;input:
4771
; v_size - размер квадрата с вокселем
4772
; k_scale - степень детализации изображения
4773
; n_plane - номер плоскости сечния (в пределах от 0 до 2^k_scale - 1)
4774
; b_color - цвет границы
4775
align 4
4776
proc buf_vox_obj_draw_pl, buf_i:dword, v_obj:dword, coord_x:dword,\
4777
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword
4778
	cmp [k_scale],0
4779
	jl .end_f
4780
pushad
4781
	mov eax,[v_size]
4782
	mov ecx,[k_scale]
4783
	mov ebx,eax
4784
	cmp ecx,1
4785
	jl @f
4786
		shl ebx,cl
4787
	@@:
4788
	;ebx - полный размер изображения
4789
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
4790
	mov edx,ebx
4791
	add ebx,[coord_y]
4792
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
4793
 
4794
	;рисование точек для сетки
4795
	push ecx
4796
	mov edi,1
4797
	cmp ecx,1
4798
	jl @f
4799
		shl edi,cl
4800
	@@:
4801
	dec edi
4802
	cmp edi,1
4803
	jl .end_0
4804
	mov ecx,edi
4805
	imul ecx,edi
4806
	mov ebx,[coord_x]
4807
	mov edx,[coord_y]
4808
	add edx,eax
4809
	xor esi,esi
4810
	cld
4811
	@@:
4812
		add ebx,eax
4813
		inc esi
4814
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
4815
		cmp esi,edi
4816
		jl .end_1
4817
			;переход точек на новую строку
4818
			xor esi,esi
4819
			mov ebx,[coord_x]
4820
			add edx,eax
4821
		.end_1:
4822
		loop @b
4823
	.end_0:
4824
	pop ecx
4825
 
4826
	;eax - размер одного квадрата
2815 IgorA 4827
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 4828
	mov ebx,[coord_x]
4829
	mov edx,[coord_y]
4830
	mov edi,[v_obj]
4831
	add edi,vox_offs_data
4832
	xor esi,esi
4833
	push eax
2815 IgorA 4834
	mov eax,1
4835
	shl eax,cl
4836
	dec eax
4837
	sub eax,[n_plane]
4838
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],eax
2758 IgorA 4839
popad
4840
	.end_f:
4841
	ret
4842
endp
4843
 
4844
;description:
4845
; функция рисующая срез части воксельного обьекта
4846
;input:
4847
; s_c_x, s_c_y, s_c_z, s_k_scale - параметры определяющие часть воксельного объекта, которая будет рисоваться
4848
align 4
4849
proc buf_vox_obj_draw_pl_scaled, buf_i:dword, v_obj:dword, coord_x:dword,\
4850
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword,\
4851
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword
4852
	cmp [k_scale],0
4853
	jl .end_f
4854
pushad
4855
locals
4856
	p_node dd 0 ;родительский узел
4857
endl
4858
	mov eax,[v_size]
4859
	mov ecx,[k_scale]
4860
	mov ebx,eax
4861
	cmp ecx,1
4862
	jl @f
4863
		shl ebx,cl
4864
	@@:
4865
	;ebx - полный размер изображения
4866
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;рамка на рисунок
4867
	mov edx,ebx
4868
	add ebx,[coord_y]
4869
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;ползунок, показывающий номер сечения
4870
 
4871
	;рисование точек для сетки
4872
	push ecx
4873
	mov edi,1
4874
	cmp ecx,1
4875
	jl @f
4876
		shl edi,cl
4877
	@@:
4878
	dec edi
4879
	cmp edi,1
4880
	jl .end_3
4881
	mov ecx,edi
4882
	imul ecx,edi
4883
	mov ebx,[coord_x]
4884
	mov edx,[coord_y]
4885
	add edx,eax
4886
	xor esi,esi
4887
	cld
4888
	@@:
4889
		add ebx,eax
4890
		inc esi
4891
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
4892
		cmp esi,edi
4893
		jl .end_4
4894
			;переход точек на новую строку
4895
			xor esi,esi
4896
			mov ebx,[coord_x]
4897
			add edx,eax
4898
		.end_4:
4899
		loop @b
4900
	.end_3:
4901
	pop ecx
4902
 
4903
	mov esi,[s_k_scale]
4904
	cmp esi,1
4905
	jl .end_2
4906
	mov edi,[v_obj]
4907
	add edi,vox_offs_data
4908
 
4909
	; *** (1) ***
4910
	.found:
4911
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
4912
	movzx bx,byte[edi+3]
4913
	mov [p_node],edi
4914
	add edi,4
4915
	cmp eax,0
4916
	je .end_1
4917
	mov ecx,eax
4918
	cld
4919
	@@: ;цикл для пропуска предыдущих поддеревьев в узле
4920
		bt bx,0 ;проверяем есть ли дочерние узлы
4921
		jnc .end_0
4922
			xor eax,eax
4923
			stdcall vox_obj_rec0 ;в eax вычисляется число дочерних узлов, в данной ветви
4924
		.end_0:
4925
		shr bx,1
4926
		loop @b
4927
	.end_1:
4928
	bt bx,0
4929
	jnc .end_2 ;если поддерева не существует
4930
	dec esi
4931
	cmp esi,0
4932
	jg .found
4933
 
4934
	mov eax,[v_size]
4935
	;eax - размер одного квадрата
2815 IgorA 4936
	;edi - указатель на рисуемые данные из объекта
2758 IgorA 4937
	mov ecx,[k_scale]
4938
	mov ebx,[coord_x]
4939
	mov edx,[coord_y]
4940
	xor esi,esi
4941
	push eax
2815 IgorA 4942
	mov eax,1
4943
	shl eax,cl
4944
	dec eax
4945
	sub eax,[n_plane]
2758 IgorA 4946
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj], eax
4947
 
4948
	.end_2:
4949
popad
4950
	.end_f:
4951
	ret
4952
endp
4953
 
4954
;description:
4955
; определение позиции узла в дереве (от 0 до 7)
4956
align 4
4957
proc vox_obj_get_node_position uses ebx ecx edi, v_obj:dword,\
4958
coord_x:dword,coord_y:dword,coord_z:dword,k_scale:dword
4959
	mov ecx,[k_scale]
4960
	dec ecx
4961
	mov eax,[coord_x]
4962
	mov ebx,[coord_y]
4963
	mov edi,[coord_z]
4964
	cmp ecx,1
4965
	jl .end_0
4966
		shr eax,cl
4967
		shr ebx,cl
4968
		shr edi,cl
4969
	.end_0:
4970
	and eax,1
4971
	bt ebx,0
4972
	jnc @f
4973
		bts eax,1
4974
	@@:
4975
	bt edi,0
4976
	jnc @f
4977
		bts eax,2
4978
	@@:
4979
 
4980
	mov edi,[v_obj]
4981
	add edi,vox_offs_tree_table
4982
	@@:
4983
		cmp al,byte[edi]
4984
		je @f
4985
		inc edi
4986
		jmp @b
4987
	@@:
4988
	sub edi,[v_obj]
4989
	sub edi,vox_offs_tree_table
4990
	mov eax,edi
4991
 
4992
	ret
4993
endp
4994
 
4995
;input:
4996
; edi - указатель на данные воксельного объекта
4997
;output:
4998
; eax - eax + число узлов в данных вокс. объекта
4999
; edi - указатель на смещенные данные вокс. объекта
5000
align 4
5001
proc vox_obj_rec0
5002
	inc eax
5003
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
5004
	je .sub_trees
5005
 
5006
		;рекурсивный перебор поддеревьев
5007
		push ebx ecx
5008
		mov bh,byte[edi+3]
5009
		add edi,4
5010
		mov bl,8
5011
		.cycle:
5012
			bt bx,8 ;тестируем только bh
5013
			jnc .c_next
5014
				stdcall vox_obj_rec0
5015
			.c_next:
5016
			shr bh,1
5017
			dec bl
5018
			jnz .cycle
5019
		pop ecx ebx
5020
 
5021
		jmp .end_f
5022
	.sub_trees:
5023
		add edi,4
5024
	.end_f:
5025
	ret
5026
endp
5027
 
5028
;description:
5029
; функция рисующая горизонтальную полосу с ползунком
5030
align 4
5031
proc draw_polz_hor uses eax ebx ecx, buf:dword, coord_x:dword, coord_y:dword,\
5032
size_x:dword, size_y:dword, pos:dword, k_scale:dword, color:dword
5033
	mov ebx,[size_x]
5034
	stdcall buf_rect_by_size, [buf], [coord_x],[coord_y],ebx,[size_y], [color]
5035
	mov ecx,[k_scale]
5036
	shr ebx,cl
5037
	mov eax,[pos]
5038
	imul eax,ebx
5039
	add eax,[coord_x]
5040
	stdcall buf_filled_rect_by_size, [buf], eax,[coord_y],ebx,[size_y], [color]
5041
	ret
5042
endp
5043
 
5044
;input:
5045
; ebx - coord_x
5046
; edx - coord_y
5047
; esi - coord_z
5048
; ecx - уровень текушего узла
5049
; edi - указатель на данные воксельного объекта
5050
align 4
5051
proc draw_sub_vox_obj_pl, buf_i:dword, v_obj:dword, clip_z:dword,\
5052
v_size:dword
5053
	cmp byte[edi+3],0 ;смотрим есть ли поддеревья
5054
	je .sub_trees
5055
 
5056
		;прорисовка рамки если размер узла = 1
5057
		cmp ecx,0
5058
		jne @f
2815 IgorA 5059
			;проверка глубины esi
5060
			;clip_z=n_plane
5061
			stdcall vox_is_clip, [clip_z];,[v_size]
5062
			cmp eax,0
5063
			je @f
5064
				push ecx
5065
				mov ecx,dword[edi]
5066
				and ecx,0xffffff
5067
				stdcall buf_rect_by_size, [buf_i], ebx,edx, [v_size],[v_size],ecx
5068
				pop ecx
2758 IgorA 5069
		@@:
5070
 
5071
		;рекурсивный перебор поддеревьев
5072
		push edx
5073
		;вход внутрь узла
5074
		dec ecx
5075
 
5076
		mov eax,[v_size]
5077
		cmp ecx,1
5078
		jl @f
5079
			shl eax,cl
5080
		@@:
2815 IgorA 5081
 
2758 IgorA 5082
		add edx,eax ;коректировка высоты под воксель нижнего уровня
5083
 
5084
		mov ah,byte[edi+3]
5085
		add edi,4
5086
		mov al,8
5087
		.cycle:
5088
			bt ax,8 ;тестируем только ah
5089
			jnc .c_next
5090
				push eax ebx edx esi
5091
				stdcall vox_corect_coords_pl, [v_obj],[v_size]
5092
				stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],[clip_z],[v_size]
5093
				pop esi edx ebx eax
5094
			.c_next:
5095
			shr ah,1
5096
			dec al
5097
			jnz .cycle
5098
		;выход из узла
5099
		inc ecx
5100
		pop edx
5101
		jmp .end_f
5102
	.sub_trees:
5103
		cmp ecx,0
5104
		jl .end_0 ;не рисуем очень маленькие воксели
5105
 
2815 IgorA 5106
			;проверка глубины esi
5107
			;clip_z=n_plane
5108
			stdcall vox_is_clip, [clip_z]
5109
			cmp eax,0
5110
			je .end_0
2758 IgorA 5111
 
2815 IgorA 5112
			;рисуем узел
5113
			mov eax,[edi]
5114
			and eax,0xffffff
5115
			push eax ;цвет узла
2758 IgorA 5116
 
2815 IgorA 5117
			mov eax,[v_size]
5118
			cmp ecx,1
5119
			jl @f
5120
				;квадрат больше текущего масштаба
5121
				shl eax,cl ;размер узла
5122
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
5123
				push ebx edx esi
5124
				mov esi,eax
5125
				inc ebx
5126
				inc edx
5127
				sub esi,2
5128
				mov eax,[buf_i]
5129
				push dword 128
5130
				push dword[eax+16] ;+16 - b_color
5131
				stdcall combine_colors_3,[edi]
5132
				stdcall buf_rect_by_size, [buf_i], ebx,edx, esi,esi,eax
5133
				pop esi edx ebx
5134
				jmp .end_0
5135
			@@:
5136
				;квадрат текущего масштаба
5137
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
2758 IgorA 5138
		.end_0:
5139
		add edi,4
5140
	.end_f:
5141
	ret
5142
endp
5143
 
5144
;description:
5145
; вспомогательная функция для проверки глубины esi
5146
;input:
5147
; ecx - уровень текушего узла
5148
; esi - coord z
2815 IgorA 5149
; clip_z - n_plane
2758 IgorA 5150
;output:
5151
; eax - 0 if no draw, 1 if draw
5152
align 4
2815 IgorA 5153
proc vox_is_clip uses ebx edi, clip_z:dword
2758 IgorA 5154
	xor eax,eax
5155
	mov ebx,[clip_z]
2815 IgorA 5156
	mov edi,1
2758 IgorA 5157
	cmp ecx,1
5158
	jl @f
5159
		shl edi,cl
5160
	@@:
5161
	;edi = 2^ecx
5162
	add edi,esi
2815 IgorA 5163
	cmp edi,ebx ;if (esi+2^ecx <= n_plane) no draw
2758 IgorA 5164
	jle @f
2815 IgorA 5165
	inc ebx
5166
	cmp esi,ebx ;if (esi >= (n_plane+1)) no draw
2758 IgorA 5167
	jge @f
5168
		inc eax
5169
	@@:
5170
	ret
5171
endp
5172
 
5173
;функция для коректировки координат
5174
;направления осей координат в вокселе:
5175
;*z
5176
;|
5177
;+-* x
5178
;input:
5179
;  al - номер узла в дереве (от 1 до 8)
5180
; ebx - координата x
5181
; edx - координата y
5182
; esi - координата z
5183
; ecx - уровень текушего узла
5184
;output:
5185
; ebx - новая координата x
5186
; edx - новая координата y
5187
; esi - новая координата z
5188
align 4
5189
proc vox_corect_coords_pl, v_obj:dword, v_size:dword
5190
	cmp ecx,0
5191
	jl .end_f ;для ускорения отрисовки
5192
 
5193
	push eax edi
5194
	and eax,15 ;выделяем номер узла в дереве
5195
	mov edi,[v_obj]
5196
	add edi,vox_offs_tree_table
5197
	add edi,8
5198
	sub edi,eax
5199
 
2815 IgorA 5200
	mov eax,[v_size]
2758 IgorA 5201
	cmp ecx,1
2815 IgorA 5202
	jl @f
2758 IgorA 5203
		shl eax,cl
5204
	@@:
5205
 
5206
	bt word[edi],0 ;test voxel coord x
5207
	jnc @f
5208
		add ebx,eax
5209
	@@:
5210
	bt word[edi],2 ;test voxel coord z
5211
	jnc @f
5212
		sub edx,eax
5213
	@@:
2815 IgorA 5214
	bt word[edi],1 ;test voxel coord y
5215
	jc @f
5216
		mov eax,1
5217
		cmp ecx,1
5218
		jl .end_0
5219
			shl eax,cl
5220
		.end_0:
5221
		add esi,eax ;меняем глубину для буфера z
5222
	@@:
2758 IgorA 5223
	pop edi eax
5224
	.end_f:
5225
	ret
5226
endp
5227
 
5228
;description:
5229
; функция рисующая тени
5230
;input:
5231
; buf_i - буфер в котором рисуется (24 бита)
5232
; buf_z - буфер глубины (32 бита по числу пикселей должен совпадать с buf_i)
5233
; h_br - кисть с изображениями вокселей (32 бита)
5234
; k_scale - коэф. для масштабирования изображения
5235
align 4
5236
proc buf_vox_obj_draw_3g_shadows, buf_i:dword, buf_z:dword, h_br:dword, \
5237
coord_x:dword, coord_y:dword, color:dword, k_scale:dword, prop:dword
5238
locals
5239
	correct_z dd 0 ;коректировка для буфера глубины
5240
endl
5241
pushad
5242
	mov eax,[k_scale]
5243
	add eax,[prop]
5244
	mov dword[correct_z],8
5245
	sub [correct_z],eax
5246
	mov ebx,[coord_x]
5247
	;correct_z = 8-k_scale-prop
5248
 
5249
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
5250
	mov edx,eax ;edx - ширина изображения
5251
	stdcall buf_vox_obj_get_img_h_3g, [h_br],[k_scale]
5252
	mov esi,eax
5253
 
5254
	mov edi,[coord_y]
5255
	mov ecx,edx
5256
	add edx,ebx ;ширина + отступ слева
5257
	imul ecx,esi
5258
	cld
5259
	.cycle_0:
5260
		stdcall buf_get_pixel, [buf_z],ebx,edi
5261
		cmp eax,0
5262
		je @f
5263
			stdcall vox_correct_z, [correct_z]
5264
			push eax
5265
			stdcall buf_get_pixel, [buf_i],ebx,edi
5266
			stdcall combine_colors_3,eax,[color] ;,eax
5267
			stdcall buf_set_pixel, [buf_i],ebx,edi,eax
5268
		@@:
5269
		inc ebx
5270
		cmp ebx,edx
5271
		jl @f
5272
			mov ebx,[coord_x]
5273
			inc edi
5274
		@@:
5275
		loop .cycle_0
5276
 
5277
popad
5278
	ret
5279
endp
5280
 
5281
;output:
5282
; eax - scaled coord z
5283
align 4
5284
proc vox_correct_z uses ecx, correct_z:dword
5285
	mov ecx,[correct_z]
5286
	cmp ecx,0
5287
	je .end_f
5288
	jl .end_0
5289
		shl eax,cl
5290
		jmp .end_f
5291
	.end_0:
5292
		neg ecx
5293
		inc ecx
5294
		shr eax,cl
5295
	.end_f:
5296
	ret
5297
endp
5298
 
5299
;output:
5300
; eax - color
5301
align 4
5302
proc combine_colors_3 uses ebx ecx edx edi esi, col_0:dword, col_1:dword, alpha:dword
5303
 
5304
	mov ebx,[col_0]
5305
	mov ecx,[col_1]
5306
	movzx di,byte[alpha] ;pro
5307
	mov si,0x00ff ;---get transparent---
5308
	sub si,di ;256-pro
5309
 
5310
	;---blye---
5311
	movzx ax,bl
5312
	imul ax,si
5313
	movzx dx,cl
5314
	imul dx,di
5315
	add ax,dx
5316
	mov cl,ah
5317
	;---green---
5318
	movzx ax,bh
5319
	imul ax,si
5320
	movzx dx,ch
5321
	imul dx,di
5322
	add ax,dx
5323
	mov ch,ah
5324
	shr ebx,16
5325
	ror ecx,16
5326
	;---red---
5327
	movzx ax,bl
5328
	imul ax,si
5329
	movzx dx,cl
5330
	imul dx,di
5331
	add ax,dx
5332
 
5333
	shl eax,8
5334
	ror ecx,16
5335
	mov ax,cx
5336
	and eax,0xffffff
5337
 
5338
	ret
5339
endp
5340
 
1535 IgorA 5341
txt_err_n8b db 'need buffer 8 bit',13,10,0
5342
txt_err_n24b db 'need buffer 24 bit',13,10,0
2815 IgorA 5343
txt_err_n32b db 'need buffer 32 bit',13,10,0
2358 IgorA 5344
txt_err_n8_24b db 'need buffer 8 or 24 bit',13,10,0
1535 IgorA 5345
 
5346
align 16
5347
EXPORTS:
5348
	dd sz_lib_init, lib_init
5349
	dd sz_buf2d_create, buf_create
5350
	dd sz_buf2d_create_f_img, buf_create_f_img
5351
	dd sz_buf2d_clear, buf_clear
5352
	dd sz_buf2d_draw, buf_draw_buf
5353
	dd sz_buf2d_delete, buf_delete
2136 IgorA 5354
	dd sz_buf2d_resize, buf_resize
2975 IgorA 5355
	dd sz_buf2d_rotate, buf_rotate
1535 IgorA 5356
	dd sz_buf2d_line, buf_line_brs
2230 IgorA 5357
	dd sz_buf2d_line_sm, buf_line_brs_sm
1634 IgorA 5358
	dd sz_buf2d_rect_by_size, buf_rect_by_size
1642 IgorA 5359
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
1535 IgorA 5360
	dd sz_buf2d_circle, buf_circle
5361
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
5362
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
5363
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
5364
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
5365
	dd sz_buf2d_bit_blt, buf_bit_blt
5366
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
5367
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1727 IgorA 5368
	dd sz_buf2d_curve_bezier, buf_curve_bezier
1535 IgorA 5369
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
5370
	dd sz_buf2d_draw_text, buf_draw_text
5371
	dd sz_buf2d_crop_color, buf_crop_color
5372
	dd sz_buf2d_offset_h, buf_offset_h
1684 IgorA 5373
	dd sz_buf2d_flood_fill, buf_flood_fill
1910 IgorA 5374
	dd sz_buf2d_set_pixel, buf_set_pixel
2658 IgorA 5375
	dd sz_buf2d_get_pixel, buf_get_pixel
5389 IgorA 5376
	dd sz_buf2d_flip_h, buf_flip_h
3040 IgorA 5377
	dd sz_buf2d_flip_v, buf_flip_v
3105 IgorA 5378
	dd sz_buf2d_filter_dither, buf_filter_dither
2748 IgorA 5379
	dd sz_buf2d_vox_brush_create, vox_brush_create
5380
	dd sz_buf2d_vox_brush_delete, vox_brush_delete
2758 IgorA 5381
	dd sz_buf2d_vox_obj_get_img_w_3g, buf_vox_obj_get_img_w_3g
5382
	dd sz_buf2d_vox_obj_get_img_h_3g, buf_vox_obj_get_img_h_3g
2815 IgorA 5383
	dd sz_buf2d_vox_obj_draw_1g, buf_vox_obj_draw_1g
2758 IgorA 5384
	dd sz_buf2d_vox_obj_draw_3g, buf_vox_obj_draw_3g
5385
	dd sz_buf2d_vox_obj_draw_3g_scaled, buf_vox_obj_draw_3g_scaled
5386
	dd sz_buf2d_vox_obj_draw_pl, buf_vox_obj_draw_pl
5387
	dd sz_buf2d_vox_obj_draw_pl_scaled, buf_vox_obj_draw_pl_scaled
5388
	dd sz_buf2d_vox_obj_draw_3g_shadows, buf_vox_obj_draw_3g_shadows
1535 IgorA 5389
	dd 0,0
5390
	sz_lib_init db 'lib_init',0
5391
	sz_buf2d_create db 'buf2d_create',0
5392
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
5393
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
5394
	sz_buf2d_draw db 'buf2d_draw',0
5395
	sz_buf2d_delete db 'buf2d_delete',0
2136 IgorA 5396
	sz_buf2d_resize db 'buf2d_resize',0
2975 IgorA 5397
	sz_buf2d_rotate db 'buf2d_rotate',0
1535 IgorA 5398
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
2230 IgorA 5399
	sz_buf2d_line_sm db 'buf2d_line_sm',0 ;рисование сглаженной линии
1642 IgorA 5400
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;рисование рамки прямоугольника, 2-я координата задана по размеру
5401
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;рисование залитого прямоугольника, 2-я координата задана по размеру
1535 IgorA 5402
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
5403
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
5404
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
5405
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
5406
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
5407
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
5408
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
5409
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1727 IgorA 5410
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
1535 IgorA 5411
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
5412
	sz_buf2d_draw_text db 'buf2d_draw_text',0
5413
	sz_buf2d_crop_color db 'buf2d_crop_color',0
5414
	sz_buf2d_offset_h db 'buf2d_offset_h',0
1684 IgorA 5415
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
1910 IgorA 5416
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
2658 IgorA 5417
	sz_buf2d_get_pixel db 'buf2d_get_pixel',0
5389 IgorA 5418
	sz_buf2d_flip_h db 'buf2d_flip_h',0
3040 IgorA 5419
	sz_buf2d_flip_v db 'buf2d_flip_v',0
3105 IgorA 5420
	sz_buf2d_filter_dither db 'buf2d_filter_dither',0
2748 IgorA 5421
	sz_buf2d_vox_brush_create db 'buf2d_vox_brush_create',0
5422
	sz_buf2d_vox_brush_delete db 'buf2d_vox_brush_delete',0
2758 IgorA 5423
	sz_buf2d_vox_obj_get_img_w_3g db 'buf2d_vox_obj_get_img_w_3g',0
5424
	sz_buf2d_vox_obj_get_img_h_3g db 'buf2d_vox_obj_get_img_h_3g',0
2815 IgorA 5425
	sz_buf2d_vox_obj_draw_1g db 'buf2d_vox_obj_draw_1g',0
2758 IgorA 5426
	sz_buf2d_vox_obj_draw_3g db 'buf2d_vox_obj_draw_3g',0
5427
	sz_buf2d_vox_obj_draw_3g_scaled db 'buf2d_vox_obj_draw_3g_scaled',0
5428
	sz_buf2d_vox_obj_draw_pl db 'buf2d_vox_obj_draw_pl',0
5429
	sz_buf2d_vox_obj_draw_pl_scaled db 'buf2d_vox_obj_draw_pl_scaled',0
5430
	sz_buf2d_vox_obj_draw_3g_shadows db 'buf2d_vox_obj_draw_3g_shadows',0