Subversion Repositories Kolibri OS

Rev

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

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