Subversion Repositories Kolibri OS

Rev

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

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