Subversion Repositories Kolibri OS

Rev

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

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