Subversion Repositories Kolibri OS

Rev

Rev 2658 | Rev 2758 | 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
 
252
		call combine_colors
253
	pop esi edi edx ebx eax
254
	@@:
255
	ret
256
endp
257
 
1535 IgorA 258
;создание буфера
259
align 4
260
proc buf_create, buf_struc:dword
261
	pushad
262
	mov edi,dword[buf_struc]
263
	mov ecx,buf2d_w
264
	mov ebx,buf2d_h
265
	imul ecx,ebx
266
	cmp buf2d_bits,24
267
	jne @f
268
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
269
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
270
	@@:
271
	cmp buf2d_bits,32
272
	jne @f
273
		shl ecx,2 ; 32 bit = 4
274
	@@:
275
	invoke mem.alloc,ecx
276
	mov buf2d_data,eax
277
 
278
	stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
279
	popad
280
	ret
281
endp
282
 
283
;создание буфера на основе изображения rgb
284
align 4
285
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
286
	pushad
287
	mov edi,dword[buf_struc]
288
	mov ecx,buf2d_w
289
	mov ebx,buf2d_h
290
	imul ecx,ebx
291
	cmp buf2d_bits,24
292
	jne @f
293
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
294
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
295
	@@:
296
	cmp buf2d_bits,32
297
	jne @f
298
		shl ecx,2 ; 32 bit = 4
299
	@@:
300
	invoke mem.alloc,ecx
301
	mov buf2d_data,eax
302
 
303
	cmp buf2d_bits,24
304
	jne @f
305
		cld
306
		mov esi,[rgb_data]
307
		mov edi,eax ;eax=buf2d_data
308
		rep movsb ;копируем биты изображения в буфер
309
		jmp .end_create
310
	@@:
311
		stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
312
	.end_create:
313
	popad
314
	ret
315
endp
316
 
317
align 4
318
proc buf_clear, buf_struc:dword, color:dword ;очистка буфера заданым цветом
319
	pushad
320
	mov edi,dword[buf_struc]
321
 
322
	mov ecx,buf2d_w
323
	mov ebx,buf2d_h
324
	imul ecx,ebx
325
 
326
	cld
327
 
328
	cmp buf2d_bits,8
329
	jne .end_clear_8
330
		mov edi,buf2d_data
331
		mov al,byte[color]
332
		rep stosb
333
		jmp .end_clear_32
334
	.end_clear_8:
335
 
336
	cmp buf2d_bits,24
337
	jne .end_clear_24
338
		mov edi,buf2d_data
339
		mov eax,dword[color]
340
		mov ebx,eax
341
		shr ebx,16
342
		@@:
343
			stosw
344
			mov byte[edi],bl
345
			inc edi
346
			loop @b
347
		jmp .end_clear_32
348
	.end_clear_24:
349
 
350
	cmp buf2d_bits,32
351
	jne .end_clear_32
352
		mov edi,buf2d_data
353
		mov eax,dword[color]
354
		rep stosd
355
		;jmp .end_clear_32
356
	.end_clear_32:
357
	popad
358
	ret
359
endp
360
 
1538 IgorA 361
;функция для обрезания буферов 8 и 24 битных, по заданому цвету.
362
;параметр opt задается комбинацией констант:
363
; BUF2D_OPT_CROP_TOP - обрезка сверху
364
; BUF2D_OPT_CROP_LEFT - обрезка слева
365
; BUF2D_OPT_CROP_BOTTOM - обрезка снизу
366
; BUF2D_OPT_CROP_RIGHT - обрезка справа
1535 IgorA 367
align 4
1538 IgorA 368
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
1535 IgorA 369
locals
370
	crop_r dd ?
371
endl
372
	pushad
373
	mov edi,dword[buf_struc]
374
	cmp buf2d_bits,24
375
	jne .24end_f
376
 
377
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
378
	jae .24no_crop_bottom
379
		mov eax,dword[color]
380
		mov edx,eax ;ax = colors - r,g
381
		shr edx,16 ;dl = color - b
382
		mov ecx,buf2d_h
1555 IgorA 383
		cmp ecx,1
384
		jle .24no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 385
		mov ebx,buf2d_w
386
		imul ecx,ebx
387
		lea esi,[ecx+ecx*2] ;esi=3*ecx
388
		add esi,buf2d_data
389
		cld
390
		@@:
391
			sub esi,3
392
			cmp word[esi],ax
393
			jne @f
394
			cmp byte[esi+2],dl
395
			jne @f
396
			loop @b
397
		@@:
398
		lea ebx,[ebx+ebx*2]
399
		xor edx,edx
400
		mov eax,buf2d_h
401
		imul eax,ebx
402
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
403
		@@:
404
			add esi,ebx
405
			cmp esi,eax
406
			jge @f
407
			inc edx ;вычисляем число полных строк для обрезания
408
			loop @b
409
		@@:
410
		cmp edx,0
411
		je .24no_crop_bottom
412
			cmp edx,buf2d_h
413
			jge .24no_crop_bottom ;что-бы не получить пустой буфер
414
			sub buf2d_h,edx ;уменьшаем высоту буфера
415
			mov ecx,buf2d_h
416
			imul ecx,ebx ;ecx = новый размер изображения
417
			invoke mem.realloc,buf2d_data,ecx
418
			mov buf2d_data,eax ;на случай если изменился указатель на данные
419
	.24no_crop_bottom:
420
 
421
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
422
	jae .24no_crop_top
423
		mov eax,dword[color]
424
		mov edx,eax ;ax = colors - r,g
425
		shr edx,16 ;dl = color - b
426
		mov esi,buf2d_data
427
		mov ecx,buf2d_h
1555 IgorA 428
		cmp ecx,1
429
		jle .24no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 430
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
431
		mov ebx,buf2d_w
432
		imul ecx,ebx
433
		cld
434
		@@:
435
			cmp word[esi],ax
436
			jne @f
437
			cmp byte[esi+2],dl
438
			jne @f
439
			add esi,3
440
			loop @b
441
		@@:
442
		lea ebx,[ebx+ebx*2]
443
		xor edx,edx
444
		@@:
445
			sub esi,ebx
446
			cmp esi,buf2d_data
447
			jl @f
448
			inc edx ;вычисляем число полных строк для обрезания
449
			loop @b
450
		@@:
451
		cmp edx,0
452
		je .24no_crop_top
453
			xor eax,eax
454
			sub eax,edx
455
			mov ebx,buf2d_h
456
			sub ebx,edx
457
			stdcall buf_offset_h, edi, eax, edx, ebx ;сдвигаем изображение в буфере вверх (eax<0)
458
			sub buf2d_h,edx ;уменьшаем высоту буфера
459
			mov ecx,buf2d_h
460
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
461
			mov ebx,buf2d_w
462
			imul ecx,ebx
463
			lea ecx,[ecx+ecx*2]
464
			invoke mem.realloc,buf2d_data,ecx
465
			mov buf2d_data,eax ;на случай если изменился указатель на данные
466
	.24no_crop_top:
467
 
468
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
469
	jae .24no_crop_right
470
		mov eax,dword[color]
471
		mov edx,eax ;ax = colors - r,g
472
		shr edx,16 ;dl = color - b
473
		mov ebx,buf2d_w
1555 IgorA 474
		cmp ebx,1
475
		jle .24no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 476
		lea ebx,[ebx+ebx*2]
477
		mov esi,ebx
478
		imul esi,buf2d_h
479
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
480
		mov dword[crop_r],0
481
		cld
1538 IgorA 482
		.24found_beg_right:
1535 IgorA 483
		sub esi,3 ;двигаемся на 1-ну колонку влево
484
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
485
		@@:
486
			cmp word[esi],ax
1538 IgorA 487
			jne .24found_right
1535 IgorA 488
			cmp byte[esi+2],dl
1538 IgorA 489
			jne .24found_right
1535 IgorA 490
			sub esi,ebx ;прыгаем на верхнюю строку
491
			loop @b
492
		inc dword[crop_r]
493
 
494
		mov ecx,buf2d_w
495
		dec ecx ;1 колонка на запас
496
		cmp dword[crop_r],ecx
1538 IgorA 497
		jge .24found_right
1535 IgorA 498
 
499
		sub esi,3 ;двигаемся на 1-ну колонку влево
500
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
501
		@@:
502
			add esi,ebx ;прыгаем на нижнюю строку
503
			cmp word[esi],ax
1538 IgorA 504
			jne .24found_right
1535 IgorA 505
			cmp byte[esi+2],dl
1538 IgorA 506
			jne .24found_right
1535 IgorA 507
			loop @b
508
		inc dword[crop_r]
509
 
510
		mov ecx,buf2d_w
511
		dec ecx ;1 колонка на запас
512
		cmp dword[crop_r],ecx
1538 IgorA 513
		jl .24found_beg_right
1535 IgorA 514
 
1538 IgorA 515
		.24found_right:
1535 IgorA 516
		cmp dword[crop_r],0
517
		je .24no_crop_right
518
			mov ecx,buf2d_w
519
			sub ecx,dword[crop_r]
1538 IgorA 520
			stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 521
			mov buf2d_w,ecx ;ставим новую ширину для буфера
522
			mov ebx,buf2d_h
523
			imul ecx,ebx
524
			lea ecx,[ecx+ecx*2]
525
			invoke mem.realloc,buf2d_data,ecx
526
			mov buf2d_data,eax ;на случай если изменился указатель на данные
527
	.24no_crop_right:
528
 
1538 IgorA 529
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
530
	jae .24no_crop_left
531
		mov eax,dword[color]
532
		mov edx,eax ;ax = colors - r,g
533
		shr edx,16 ;dl = color - b
534
		mov ebx,buf2d_w
1555 IgorA 535
		cmp ebx,1
536
		jle .24no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 537
		lea ebx,[ebx+ebx*2]
538
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
539
		mov dword[crop_r],0
540
		cld
541
		.24found_beg_left:
542
 
543
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
544
		@@:
545
			cmp word[esi],ax
546
			jne .24found_left
547
			cmp byte[esi+2],dl
548
			jne .24found_left
549
			add esi,ebx ;прыгаем на нижнюю строку
550
			loop @b
551
		inc dword[crop_r]
552
		add esi,3 ;двигаемся на 1-ну колонку вправо
553
 
554
		mov ecx,buf2d_w
555
		dec ecx ;1 колонка на запас
556
		cmp dword[crop_r],ecx
557
		jge .24found_left
558
 
559
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
560
		@@:
561
			sub esi,ebx ;прыгаем на верхнюю строку
562
			cmp word[esi],ax
563
			jne .24found_left
564
			cmp byte[esi+2],dl
565
			jne .24found_left
566
			loop @b
567
		inc dword[crop_r]
568
		add esi,3 ;двигаемся на 1-ну колонку вправо
569
 
570
		mov ecx,buf2d_w
571
		dec ecx ;1 колонка на запас
572
		cmp dword[crop_r],ecx
573
		jl .24found_beg_left
574
 
575
		.24found_left:
576
		cmp dword[crop_r],0
577
		je .24no_crop_left
578
			mov ecx,buf2d_w
579
			sub ecx,dword[crop_r]
580
			stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
581
			mov buf2d_w,ecx ;ставим новую ширину для буфера
582
			mov ebx,buf2d_h
583
			imul ecx,ebx
584
			lea ecx,[ecx+ecx*2]
585
			invoke mem.realloc,buf2d_data,ecx
586
			mov buf2d_data,eax ;на случай если изменился указатель на данные
587
			mov eax,dword[crop_r]
588
			add buf2d_l,ax
589
	.24no_crop_left:
590
 
1535 IgorA 591
	.24end_f:
592
 
593
 
594
	cmp buf2d_bits,8
595
	jne .8end_f
596
 
597
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
598
	jae .8no_crop_bottom
599
		mov eax,dword[color]
600
		mov esi,buf2d_data
601
		mov ecx,buf2d_h
1555 IgorA 602
		cmp ecx,1
603
		jle .8no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 604
		mov ebx,buf2d_w
605
		imul ecx,ebx
606
		mov esi,ecx
607
		add esi,buf2d_data
608
		cld
609
		@@:
610
			dec esi
611
			cmp byte[esi],al
612
			jne @f
613
			loop @b
614
		@@:
615
		xor edx,edx
616
		mov eax,buf2d_h
617
		imul eax,ebx
618
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
619
		@@:
620
			add esi,ebx
621
			cmp esi,eax
622
			jge @f
623
			inc edx
624
			loop @b
625
		@@:
626
		cmp edx,0
627
		je .8no_crop_bottom
628
			cmp edx,buf2d_h
629
			jge .8no_crop_bottom ;что-бы не получить пустой буфер
630
			sub buf2d_h,edx ;уменьшаем высоту буфера
631
			mov ecx,buf2d_h
632
			imul ecx,ebx ;ecx = новый размер изображения
633
			invoke mem.realloc,buf2d_data,ecx
634
			mov buf2d_data,eax ;на случай если изменился указатель на данные
635
	.8no_crop_bottom:
636
 
637
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
638
	jae .8no_crop_top
639
		mov eax,dword[color]
640
		mov esi,buf2d_data
641
		mov ecx,buf2d_h
1555 IgorA 642
		cmp ecx,1
643
		jle .8no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 644
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
645
		mov ebx,buf2d_w
646
		imul ecx,ebx
647
		cld
648
		@@:
649
			cmp byte[esi],al
650
			jne @f
651
			inc esi
652
			loop @b
653
		@@:
654
		xor edx,edx
655
		@@:
656
			sub esi,ebx
657
			cmp esi,buf2d_data
658
			jl @f
659
			inc edx
660
			loop @b
661
		@@:
662
		cmp edx,0
663
		je .8no_crop_top
664
			xor eax,eax
665
			sub eax,edx
666
			mov ebx,buf2d_h
667
			sub ebx,edx
668
			stdcall buf_offset_h, edi, eax, edx, ebx
669
			mov ecx,buf2d_h
670
			sub ecx,edx
671
			mov buf2d_h,ecx ;уменьшаем высоту буфера
672
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
673
			mov ebx,buf2d_w
674
			imul ecx,ebx
675
			invoke mem.realloc,buf2d_data,ecx
676
			mov buf2d_data,eax ;на случай если изменился указатель на данные
677
	.8no_crop_top:
678
 
679
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
680
	jae .8no_crop_right
681
		mov eax,dword[color]
682
		mov ebx,buf2d_w
1555 IgorA 683
		cmp ebx,1
684
		jle .8no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 685
		mov esi,ebx
686
		imul esi,buf2d_h
687
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
688
		xor edx,edx
689
		cld
690
 
691
		.8found_beg:
692
		dec esi ;двигаемся на 1-ну колонку влево
693
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
694
		@@:
695
			cmp byte[esi],al
696
			jne .8found
697
			sub esi,ebx ;прыгаем на верхнюю строку
698
			loop @b
699
		inc edx
700
		mov ecx,buf2d_w
701
		dec ecx ;1 колонка на запас
702
		cmp edx,ecx
703
		jge .8found
704
 
705
		dec esi ;двигаемся на 1-ну колонку влево
706
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
707
		@@:
708
			add esi,ebx ;прыгаем на нижнюю строку
709
			cmp byte[esi],al
710
			jne .8found
711
			loop @b
712
		inc edx
713
 
714
		mov ecx,buf2d_w
715
		dec ecx ;1 колонка на запас
716
		cmp edx,ecx
717
		jl .8found_beg
718
 
719
		.8found:
720
		cmp edx,0
721
		je .8no_crop_right
722
			mov ecx,buf2d_w
723
			sub ecx,edx
1538 IgorA 724
			stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 725
			mov buf2d_w,ecx ;ставим новую ширину для буфера
726
			mov ebx,buf2d_h
727
			imul ecx,ebx
728
			invoke mem.realloc,buf2d_data,ecx
729
			mov buf2d_data,eax ;на случай если изменился указатель на данные
730
	.8no_crop_right:
731
 
1538 IgorA 732
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
733
	jae .8no_crop_left
734
		mov eax,dword[color]
735
		mov ebx,buf2d_w
1555 IgorA 736
		cmp ebx,1
737
		jle .8no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 738
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
739
		mov edx,0
740
		cld
741
		.8found_beg_left:
742
 
743
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
744
		@@:
745
			cmp word[esi],ax
746
			jne .8found_left
747
			add esi,ebx ;прыгаем на нижнюю строку
748
			loop @b
749
		inc edx
750
		inc esi ;двигаемся на 1-ну колонку вправо
751
 
752
		mov ecx,buf2d_w
753
		dec ecx ;1 колонка на запас
754
		cmp edx,ecx
755
		jge .8found_left
756
 
757
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
758
		@@:
759
			sub esi,ebx ;прыгаем на верхнюю строку
760
			cmp word[esi],ax
761
			jne .8found_left
762
			loop @b
763
		inc edx
764
		inc esi ;двигаемся на 1-ну колонку вправо
765
 
766
		mov ecx,buf2d_w
767
		dec ecx ;1 колонка на запас
768
		cmp edx,ecx
769
		jl .8found_beg_left
770
 
771
		.8found_left:
772
		cmp edx,0
773
		je .8no_crop_left
774
			mov ecx,buf2d_w
775
			sub ecx,edx
776
			stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
777
			mov buf2d_w,ecx ;ставим новую ширину для буфера
778
			mov ebx,buf2d_h
779
			imul ecx,ebx
780
			invoke mem.realloc,buf2d_data,ecx
781
			mov buf2d_data,eax ;на случай если изменился указатель на данные
782
			mov eax,edx
783
			add buf2d_l,ax
784
	.8no_crop_left:
785
 
1535 IgorA 786
	.8end_f:
787
 
788
	popad
789
	ret
790
endp
791
 
1538 IgorA 792
;обрезаем цветное изображение с правой стороны
1535 IgorA 793
;input:
794
;data_rgb - pointer to rgb data
795
;size_w_old - width img in pixels
796
;size_w_new - new width img in pixels
797
;size_h - height img in pixels
798
align 4
1538 IgorA 799
proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 800
	pushad
801
	mov eax, dword[size_w_old]
802
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
803
	mov ebx, dword[size_w_new]
804
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
805
	mov edx, dword[size_h]
806
	mov edi, dword[data_rgb] ;edi - получает данные
807
	mov esi, edi
808
	add edi, ebx
809
	add esi, eax
810
	cld
811
	@@:
812
		dec edx ;уменьшаем счетчик оставшихся строк на 1
813
		cmp edx,0
814
		jle @f
815
		mov ecx, ebx
816
		rep movsb ;перенос (копирование) строки пикселей
817
		add esi,eax ;переход на новую строчку изображения
818
		sub esi,ebx
819
		jmp @b
820
	@@:
821
	popad
822
	ret
823
endp
824
 
1538 IgorA 825
;обрезаем серое изображение с правой стороны
1535 IgorA 826
;input:
827
;data_gray - pointer to gray data
828
;size_w_old - width img in pixels
829
;size_w_new - new width img in pixels
830
;size_h - height img in pixels
831
align 4
1538 IgorA 832
proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 833
	pushad
834
	mov eax, dword[size_w_old]
835
	mov ebx, dword[size_w_new]
836
	mov edx, dword[size_h]
837
	mov edi, dword[data_gray] ;edi - получает данные
838
	mov esi, edi
839
	add edi, ebx
840
	add esi, eax
841
	cld
842
	@@:
843
		dec edx ;уменьшаем счетчик оставшихся строк на 1
844
		cmp edx,0
845
		jle @f
846
		mov ecx, ebx
847
		rep movsb ;перенос (копирование) строки пикселей
848
		add esi,eax ;переход на новую строчку изображения
849
		sub esi,ebx
850
		jmp @b
851
	@@:
852
	popad
853
	ret
854
endp
855
 
1538 IgorA 856
;обрезаем цветное изображение с левой стороны
857
;input:
858
;data_rgb - pointer to rgb data
859
;size_w_old - width img in pixels
860
;size_w_new - new width img in pixels
861
;size_h - height img in pixels
862
align 4
863
proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
864
	pushad
865
	mov edi,dword[data_rgb]
866
	mov esi,edi
867
	mov eax,dword[size_w_old]
868
	mov ebx,dword[size_w_new]
869
	cmp eax,ebx
870
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
871
		lea eax,[eax+eax*2]
872
		lea ebx,[ebx+ebx*2]
873
		sub eax,ebx
874
		mov edx,dword[size_h] ;высота изображения
875
		cld
876
		@@:
877
			add esi,eax
878
			mov ecx,ebx
879
			rep movsb
880
			dec edx
881
			cmp edx,0
882
			jg @b
883
	.end_f:
884
	popad
885
	ret
886
endp
887
 
888
;обрезаем серое изображение с левой стороны
889
;input:
890
;data_gray - pointer to gray data
891
;size_w_old - width img in pixels
892
;size_w_new - new width img in pixels
893
;size_h - height img in pixels
894
align 4
895
proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
896
	pushad
897
	mov edi,dword[data_gray]
898
	mov esi,edi
899
	mov eax,dword[size_w_old]
900
	mov ebx,dword[size_w_new]
901
	cmp eax,ebx
902
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
903
		sub eax,ebx
904
		mov edx,dword[size_h] ;высота изображения
905
		cld
906
		@@:
907
			add esi,eax
908
			mov ecx,ebx
909
			rep movsb
910
			dec edx
911
			cmp edx,0
912
			jg @b
913
	.end_f:
914
	popad
915
	ret
916
endp
917
 
1535 IgorA 918
;hoffs - колличество пикселей на котрые поднимается/опускается изображение
919
;img_t - высота, с которой начинается двигающаяся часть изображения
920
align 4
921
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;сдвигает изображение по высоте
922
	pushad
923
	mov edi,dword[buf_struc]
924
	cmp buf2d_bits,24
925
	jne .end_move_24
926
 
927
	mov eax,[hoffs]
928
	cmp eax,0
929
	je .end_move_24
930
		mov ebx,buf2d_w
931
		mov edx,dword[img_t]
932
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
933
			cmp ecx,buf2d_h
934
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
935
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
936
			lea ecx,[ecx+ecx*2]
937
		imul ebx,edx
938
		lea ebx,[ebx+ebx*2]
939
		mov esi,buf2d_data
940
		add esi,ebx
941
 
942
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
943
		mov ebx,buf2d_w
944
		imul ebx,edx
945
		lea ebx,[ebx+ebx*2]
946
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
947
		add edi,ebx
948
 
949
		cmp eax,0
950
		jg .move_down_24
951
			;двигаем изображение вверх
952
			cld
953
			rep movsb
954
			jmp .end_f
955
		.move_down_24:
956
			;двигаем изображение вниз
957
			add esi,ecx
958
			dec esi
959
			add edi,ecx
960
			dec edi
961
			std
962
			rep movsb
963
			jmp .end_f
964
	.end_move_24:
965
 
966
;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b
967
 
968
	cmp buf2d_bits,8
969
	jne .end_move_8
970
 
971
	mov eax,[hoffs]
972
	cmp eax,0
973
	je .end_move_8
974
		;двигаем изображение вверх
975
		mov ebx,buf2d_w
976
		mov edx,dword[img_t]
977
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
978
			cmp ecx,buf2d_h
979
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
980
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
981
		imul ebx,edx
982
		mov esi,buf2d_data
983
		add esi,ebx
984
 
985
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
986
		mov ebx,buf2d_w
987
		imul ebx,edx
988
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
989
		add edi,ebx
990
 
991
		cmp eax,0
992
		jg .move_down_8
993
			cld
994
			rep movsb
995
			jmp .end_f
996
		.move_down_8:
997
			;двигаем изображение вниз
998
			add esi,ecx
999
			dec esi
1000
			add edi,ecx
1001
			dec edi
1002
			std
1003
			rep movsb
1004
			jmp .end_f
1005
	.end_move_8:
1006
 
1007
	.end_f:
1008
	popad
1009
	ret
1010
endp
1011
 
1012
 
1013
align 4
1014
proc buf_draw_buf, buf_struc:dword
1015
	pushad
1016
	mov edi,dword[buf_struc]
1017
	cmp buf2d_bits,24
1018
	jne .error
1019
		mov eax,7
1020
		mov ebx,buf2d_data
1021
 
1022
		mov ecx,buf2d_w
1023
		ror ecx,16
1024
		mov edx,buf2d_h
1025
		mov cx,dx
1026
 
1027
		mov edx,buf2d_size_lt
1028
		ror edx,16
1029
		int 0x40
1030
		jmp .end_draw_24
1031
	.error:
1032
		stdcall print_err,sz_buf2d_draw,txt_err_n24b
1033
	.end_draw_24:
1034
	popad
1035
	ret
1036
endp
1037
 
1038
align 4
1039
proc buf_delete, buf_struc:dword
2136 IgorA 1040
	push eax edi
1535 IgorA 1041
	mov edi,dword[buf_struc]
1042
	invoke mem.free,buf2d_data
2136 IgorA 1043
	pop edi eax
1535 IgorA 1044
	ret
1045
endp
1046
 
1047
align 4
2136 IgorA 1048
proc buf_resize, buf_struc:dword, new_w:dword, new_h:dword
1049
	pushad
1050
	mov edi,dword[buf_struc]
1051
	cmp buf2d_bits,24
1052
	jne .24bit
1053
		mov eax,dword[new_w]
1054
		cmp eax,1
1055
		jl @f
1056
			mov buf2d_w,eax
1057
		@@:
1058
		mov ecx,buf2d_w
1059
		mov eax,dword[new_h]
1060
		cmp eax,1
1061
		jl @f
1062
			mov buf2d_h,eax
1063
		@@:
1064
		mov ebx,buf2d_h
1065
		imul ecx,ebx
1066
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
1067
		invoke mem.realloc,buf2d_data,ecx ;изменяем память занимаемую буфером
1068
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1069
	.24bit:
1070
	popad
1071
	ret
1072
endp
1073
 
1074
align 4
1535 IgorA 1075
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1076
locals
1077
	loc_1 dd ?
1078
	loc_2 dd ?
1079
	napravl db ?
1080
endl
1081
	pushad
1082
		mov eax,dword[coord_x1]
1083
		sub eax,dword[coord_x0]
1084
		bt eax,31
1085
		jae @f
1086
			neg eax
1087
			inc eax
1088
		@@:
1089
		mov ebx,dword[coord_y1]
1090
		sub ebx,dword[coord_y0]
2230 IgorA 1091
		jnz @f
1092
			;если задана горизонтальная линия y0=y1
1093
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1094
			jmp .coord_end
1095
		@@:
1535 IgorA 1096
		bt ebx,31
1097
		jae @f
1098
			neg ebx
1099
			inc ebx
1100
		@@:
2230 IgorA 1101
		mov edx,dword[color]
1535 IgorA 1102
 
1103
		mov [napravl],byte 0 ;bool steep=false
1104
		cmp eax,ebx
1105
		jle @f
1106
			mov [napravl],byte 1 ;bool steep=true
1107
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1108
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1109
		@@:
1110
		mov eax,dword[coord_y0] ;x0
1111
		cmp eax,dword[coord_y1] ;if(x0>x1)
1112
		jle @f
1113
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1114
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1115
		@@:
1116
 
1117
; int deltax esi
1118
; int deltay edi
1119
; int error  ebp-6
1120
; int ystep  ebp-8
1121
 
1122
		mov eax,dword[coord_y0]
1123
		mov esi,dword[coord_y1]
1124
		sub esi,eax ;deltax = y1-y0
1125
		mov ebx,esi
1126
		shr ebx,1
1127
		mov [loc_1],ebx ;error = deltax/2
1128
 
1129
		mov eax,dword[coord_x0]
1130
		mov edi,dword[coord_x1]
1131
		mov [loc_2],dword -1 ;ystep = -1
1132
		cmp eax,edi ;if (x0
1133
		jge @f
1134
			mov [loc_2],dword 1 ;ystep = 1
1135
		@@:
1136
		sub edi,eax ;x1-x0
1137
 
1138
		bts edi,31
1139
		jae @f
1140
			neg edi
1141
			inc edi
1142
		@@:
1143
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1144
 
1145
		mov eax,edi
1146
		mov edi,[buf_struc]
2358 IgorA 1147
		cmp buf2d_bits,8
1148
		je @f
1535 IgorA 1149
		cmp buf2d_bits,24
2358 IgorA 1150
		je @f
1151
			jmp .coord_end
1152
		@@:
1535 IgorA 1153
 
1154
		cmp [napravl],0
1155
		jne .coord_yx
1156
			mov ebx,dword[coord_x0]
1157
			mov ecx,dword[coord_y0]
1158
 
1159
			@@: ;for (x=x0 ; x
1160
				cmp ecx,dword[coord_y1]
1161
				jg @f ;jge ???
1162
				call draw_pixel
1163
 
1164
				sub dword[loc_1],eax ;error -= deltay
1165
				cmp dword[loc_1],0 ;if(error<0)
1166
				jge .if0
1167
					add ebx,[loc_2] ;y += ystep
1168
					add [loc_1],esi ;error += deltax
1169
				.if0:
1170
				inc ecx
1171
				jmp @b
1172
			@@:
1173
			jmp .coord_end
1174
		.coord_yx:
1175
			mov ebx,dword[coord_y0]
1176
			mov ecx,dword[coord_x0]
1177
 
1178
			@@: ;for (x=x0 ; x
1179
				cmp ebx,dword[coord_y1]
1180
				jg @f ;jge ???
1181
				call draw_pixel
1182
 
1183
				sub dword[loc_1],eax ;error -= deltay
1184
				cmp dword[loc_1],0 ;if(error<0)
1185
				jge .if1
1186
					add ecx,[loc_2] ;y += ystep
1187
					add [loc_1],esi ;error += deltax
1188
				.if1:
1189
				inc ebx
1190
				jmp @b
1191
			@@:
1192
	.coord_end:
1193
	popad
1194
	ret
1195
endp
1196
 
2230 IgorA 1197
;рисование сглаженной линии
1198
align 4
1199
proc buf_line_brs_sm, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
1200
locals
1201
	loc_1 dd ?
1202
	loc_2 dd ?
1203
	napravl db ?
1204
endl
1205
	pushad
1206
		mov eax,dword[coord_x1]
1207
		sub eax,dword[coord_x0]
1208
		bt eax,31
1209
		jae @f
1210
			neg eax
1211
			inc eax
1212
		@@:
1213
		mov ebx,dword[coord_y1]
1214
		sub ebx,dword[coord_y0]
1215
		jnz @f
1216
			;если задана горизонтальная линия y0=y1
1217
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
1218
			jmp .coord_end
1219
		@@:
1220
		bt ebx,31
1221
		jae @f
1222
			neg ebx
1223
			inc ebx
1224
		@@:
1225
		mov edx,dword[color]
1226
 
1227
		mov [napravl],byte 0 ;bool steep=false
1228
		cmp eax,ebx
1229
		jle @f
1230
			mov [napravl],byte 1 ;bool steep=true
1231
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
1232
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
1233
		@@:
1234
		mov eax,dword[coord_y0] ;x0
1235
		cmp eax,dword[coord_y1] ;if(x0>x1)
1236
		jle @f
1237
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
1238
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
1239
		@@:
1240
 
1241
; int deltax esi
1242
; int deltay edi
1243
; int error  ebp-6
1244
; int ystep  ebp-8
1245
 
1246
		mov eax,dword[coord_y0]
1247
		mov esi,dword[coord_y1]
1248
		sub esi,eax ;deltax = y1-y0
1249
		mov ebx,esi
1250
		shr ebx,1
1251
		mov [loc_1],ebx ;error = deltax/2
1252
 
1253
		mov eax,dword[coord_x0]
1254
		mov edi,dword[coord_x1]
1255
		mov [loc_2],dword -1 ;ystep = -1
1256
		cmp eax,edi ;if (x0
1257
		jge @f
1258
			mov [loc_2],dword 1 ;ystep = 1
1259
		@@:
1260
		sub edi,eax ;x1-x0
1261
 
1262
		bts edi,31
1263
		jae @f
1264
			neg edi
1265
			inc edi
1266
		@@:
1267
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1268
 
1269
		mov eax,edi
1270
		mov edi,[buf_struc]
1271
		cmp buf2d_bits,24
1272
		jne .coord_end
1273
 
1274
		cmp [napravl],0
1275
		jne .coord_yx
1276
			mov ebx,dword[coord_x0]
1277
			mov ecx,dword[coord_y0]
1278
 
1279
			@@: ;for (x=x0 ; x
1280
				cmp ecx,dword[coord_y1]
1281
				jg @f ;jge ???
1282
				push eax
1283
					mov eax,esi
1284
					sub eax,[loc_1]
1285
					stdcall draw_pixel_transp, eax,esi
1286
				pop eax
1287
				add ebx,[loc_2]
1288
				stdcall draw_pixel_transp, [loc_1],esi
1289
				sub ebx,[loc_2]
1290
 
1291
				sub dword[loc_1],eax ;error -= deltay
1292
				cmp dword[loc_1],0 ;if(error<0)
1293
				jge .if0
1294
					add ebx,[loc_2] ;y += ystep
1295
					add [loc_1],esi ;error += deltax
1296
				.if0:
1297
				inc ecx
1298
				jmp @b
1299
			@@:
1300
			jmp .coord_end
1301
		.coord_yx:
1302
			mov ebx,dword[coord_y0]
1303
			mov ecx,dword[coord_x0]
1304
 
1305
			@@: ;for (x=x0 ; x
1306
				cmp ebx,dword[coord_y1]
1307
				jg @f ;jge ???
1308
				push eax
1309
					mov eax,esi
1310
					sub eax,[loc_1]
1311
					stdcall draw_pixel_transp, eax,esi
1312
				pop eax
1313
				add ecx,[loc_2]
1314
				stdcall draw_pixel_transp, [loc_1],esi
1315
				sub ecx,[loc_2]
1316
 
1317
				sub dword[loc_1],eax ;error -= deltay
1318
				cmp dword[loc_1],0 ;if(error<0)
1319
				jge .if1
1320
					add ecx,[loc_2] ;y += ystep
1321
					add [loc_1],esi ;error += deltax
1322
				.if1:
1323
				inc ebx
1324
				jmp @b
1325
			@@:
1326
	.coord_end:
1327
	popad
1328
	ret
1329
endp
1330
 
1653 IgorA 1331
;рисование горизонтальной линии, потому нет параметра coord_y1
1535 IgorA 1332
align 4
1634 IgorA 1333
proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
1334
	pushad
2358 IgorA 1335
	pushfd
1634 IgorA 1336
		mov edi,[buf_struc]
2358 IgorA 1337
		cmp buf2d_bits,8
1338
		je @f
1634 IgorA 1339
		cmp buf2d_bits,24
2358 IgorA 1340
		je @f
1341
			jmp .end24
1342
		@@: ;определение координат линии относительно буфера
1634 IgorA 1343
 
2177 IgorA 1344
		mov ecx,dword[coord_y0]
1345
		bt ecx,31
1346
		jc .end24 ;если координата y0 отрицательная
1347
		cmp ecx,buf2d_h
1348
		jge .end24 ;если координата y0 больше высоты буфера
1349
 
1634 IgorA 1350
		mov ebx,dword[coord_x0]
1351
		mov esi,dword[coord_x1]
1717 IgorA 1352
		cmp ebx,esi
1353
		jle @f
1354
			xchg ebx,esi ;если x0 > x1 то меняем местами x0 и x1
2177 IgorA 1355
		@@:
2185 IgorA 1356
		bt ebx,31
1357
		jae @f
1358
			;если координата x0 отрицательная
1359
			xor ebx,ebx
1360
		@@:
2177 IgorA 1361
		cmp esi,buf2d_w
1362
		jl @f
2185 IgorA 1363
			;если координата x0 больше ширины буфера
2177 IgorA 1364
			mov esi,buf2d_w
2359 IgorA 1365
			dec esi
2177 IgorA 1366
		@@:
2185 IgorA 1367
		cmp ebx,esi
2358 IgorA 1368
		jg .end24 ;если x0 > x1 может возникнуть когда обе координаты x0, x1 находились за одним из пределов буфера
1717 IgorA 1369
 
2358 IgorA 1370
		cmp buf2d_bits,24
1371
		je .beg24
1372
			;рисование в 8 битном буфере
1373
			;в edx вычисляем начало 1-й точки линии в буфере изображения
1374
			mov edx,buf2d_w ;size x
1375
			imul edx,ecx ;size_x*y
1376
			add edx,ebx	 ;size_x*y+x
1377
			add edx,buf2d_data ;ptr+(size_x*y+x)
1378
			mov edi,edx ;теперь можем портить указатель на буфер
1379
 
1380
			mov ecx,esi
1381
			sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
1382
			inc ecx ;что-бы последняя точка линии также отображалась
1383
			mov eax,dword[color] ;будем использовать только значение в al
1384
			cld
1385
			rep stosb ;цикл по оси x от x0 до x1 (включая x1)
1386
			jmp .end24
1387
 
1388
		.beg24: ;рисование в 24 битном буфере
2177 IgorA 1389
		;в eax вычисляем начало 1-й точки линии в буфере изображения
1390
		mov eax,buf2d_w ;size x
1391
		imul eax,ecx ;size_x*y
1392
		add eax,ebx	 ;size_x*y+x
1393
		lea eax,[eax+eax*2] ;(size_x*y+x)*3
1394
		add eax,buf2d_data  ;ptr+(size_x*y+x)*3
1395
 
2185 IgorA 1396
		mov ecx,esi
1397
		sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
2358 IgorA 1398
		inc ecx ;что-бы последняя точка линии также отображалась
2177 IgorA 1399
		mov edx,dword[color]
2185 IgorA 1400
		mov ebx,edx ;координата x0 в ebx уже не нужна
1401
		ror edx,16 ;поворачиваем регистр что бы 3-й байт попал в dl
1402
		cld
2358 IgorA 1403
		@@: ;цикл по оси x от x0 до x1 (включая x1)
2185 IgorA 1404
			mov word[eax],bx ;copy pixel color
1405
			mov byte[eax+2],dl
1406
			add eax,3
1407
			loop @b
1684 IgorA 1408
		.end24:
2358 IgorA 1409
	popfd
1634 IgorA 1410
	popad
1411
	ret
1412
endp
1413
 
1414
align 4
1415
proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1416
pushad
1417
	mov edi,[buf_struc]
2358 IgorA 1418
	cmp buf2d_bits,8
1419
	je @f
1634 IgorA 1420
	cmp buf2d_bits,24
2358 IgorA 1421
	je @f
1422
		jmp .coord_end
1423
	@@:
1634 IgorA 1424
 
1425
		mov eax,[coord_x]
1426
		mov ebx,[coord_y]
1427
		mov ecx,[w]
2358 IgorA 1428
		;cmp ecx,1
1429
		;jl .coord_end
1430
		cmp ecx,0
1431
		je .coord_end
1432
		jg @f
1433
			add eax,ecx
1434
			inc eax
1435
			neg ecx
1436
		@@:
1634 IgorA 1437
		add ecx,eax
1642 IgorA 1438
		dec ecx
1634 IgorA 1439
		mov edx,[h]
2358 IgorA 1440
		;cmp edx,1
1441
		;jl .coord_end
1442
		cmp edx,0
1443
		je .coord_end
1444
		jg @f
1445
			add ebx,edx
1446
			inc ebx
1447
			neg edx
1448
		@@:
1642 IgorA 1449
 
1634 IgorA 1450
		add edx,ebx
1642 IgorA 1451
		dec edx
1634 IgorA 1452
		mov esi,dword[color]
1453
		stdcall buf_line_h, edi, eax, ebx, ecx, esi ;линия -
1454
		stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;линия |
1455
		stdcall buf_line_h, edi, eax, edx, ecx, esi ;линия -
1456
		stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;линия |
1457
	.coord_end:
1458
popad
1459
	ret
1460
endp
1461
 
1462
align 4
1642 IgorA 1463
proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1464
pushad
1465
	mov edi,[buf_struc]
2358 IgorA 1466
	cmp buf2d_bits,8
1467
	je @f
1642 IgorA 1468
	cmp buf2d_bits,24
2358 IgorA 1469
	je @f
1470
		jmp .coord_end
1471
	@@:
1642 IgorA 1472
		mov eax,[coord_x]
1473
		mov ebx,[coord_y]
1474
		mov edx,[w]
2358 IgorA 1475
		cmp edx,0
1476
		je .coord_end ;если высота 0 пикселей
1477
		jg @f ;если высота положительная
1478
			add eax,edx
1479
			inc eax
1480
			neg edx ;ширину делаем положительной
1481
			;inc edx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1482
		@@:
1642 IgorA 1483
		add edx,eax
2358 IgorA 1484
		dec edx
1642 IgorA 1485
		mov ecx,[h]
2358 IgorA 1486
		cmp ecx,0
1487
		je .coord_end ;если высота 0 пикселей
1488
		jg @f ;если высота положительная
1489
			add ebx,ecx ;сдвигаем верхнюю координату прямоугольника
1490
			inc ebx
1491
			neg ecx ;высоту делаем положительной
1492
			;inc ecx ;почему тут не добавляем 1-цу я не знаю, но с ней работает не правильно
1493
		@@:
1642 IgorA 1494
		mov esi,dword[color]
1495
		cld
1496
		@@:
1497
			stdcall buf_line_h, edi, eax, ebx, edx, esi ;линия -
1498
			inc ebx
1499
			loop @b
1500
	.coord_end:
1501
popad
1502
	ret
1503
endp
1504
 
1505
align 4
1535 IgorA 1506
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
1507
locals
1508
	po_x dd ?
1509
	po_y dd ?
1510
endl
1511
	pushad
1512
	mov edi,dword[buf_struc]
2358 IgorA 1513
	cmp buf2d_bits,8
1514
	je @f
1535 IgorA 1515
	cmp buf2d_bits,24
2358 IgorA 1516
	je @f
1517
		jmp .error
1518
	@@:
1535 IgorA 1519
		mov edx,dword[color]
1520
 
1521
		finit
1522
		fild dword[coord_x]
1523
		fild dword[coord_y]
1524
		fild dword[r]
1525
		fldz ;px=0
1526
		fld st1 ;py=r
1527
 
1528
		fldpi
1529
		fmul st0,st3
1530
		fistp dword[po_x]
1531
		mov esi,dword[po_x] ;esi=pi*r
1532
		shl esi,1 ;esi=2*pi*r
1533
 
1534
		;st0 = py
1535
		;st1 = px
1536
		;st2 = r
1537
		;st3 = y
1538
		;st4 = x
1539
 
1540
		@@:
1541
			;Point(px + x, y - py)
1542
			fld st1 ;st0=px
1543
			fadd st0,st5 ;st0=px+x
1544
			fistp dword[po_x]
1545
			mov ebx,dword[po_x]
1546
			fld st3 ;st0=y
1547
			fsub st0,st1 ;st0=y-py
1548
			fistp dword[po_y]
1549
			mov ecx,dword[po_y]
1550
			call draw_pixel
1551
			;px += py/r
1552
			fld st0 ;st0=py
1553
			fdiv st0,st3 ;st0=py/r
1554
			faddp st2,st0 ;st3+=st0
1555
			;py -= px/r
1556
			fld st1 ;st0=px
1557
			fdiv st0,st3 ;st0=px/r
1558
			fsubp st1,st0 ;st2-=st0
1559
 
1560
			dec esi
1561
			cmp esi,0
1562
			jge @b
1563
		jmp .exit_fun
1564
	.error:
2358 IgorA 1565
		stdcall print_err,sz_buf2d_circle,txt_err_n8_24b
1535 IgorA 1566
	.exit_fun:
1567
 
1568
	popad
1569
	ret
1570
endp
1571
 
1684 IgorA 1572
;функция для заливки области выбранным цветом
1535 IgorA 1573
align 4
1684 IgorA 1574
proc buf_flood_fill, buf_struc:dword, coord_x:dword, coord_y:dword, mode:dword, color_f:dword, color_b:dword
1575
	pushad
1576
		mov edi,[buf_struc]
1577
		cmp buf2d_bits,24
1578
		jne .end24
1579
 
1580
			mov ebx,dword[coord_x]
1581
			mov ecx,dword[coord_y]
1582
			mov edx,dword[color_f]
1583
			mov esi,dword[color_b]
1584
 
1585
			cmp dword[mode],1 ;в зависимости от 'mode' определяем каким алгоритмом будем пользоваться
1586
			je @f
1587
				call buf_flood_fill_recurs_0 ;заливаем до пикселей цвета esi
1588
				jmp .end24
1589
			@@:
1590
				call buf_flood_fill_recurs_1 ;заливаем пиксели имеющие цвет esi
1591
 
1592
		.end24:
1593
	popad
1594
	ret
1595
endp
1596
 
1597
;input:
1598
; ebx = coord_x
1599
; ecx = coord_y
1600
; edx = цвет заливки
1601
; esi = цвет границы, до которой будет ити заливка
1602
; edi = buf_struc
1603
;output:
1604
; eax = портится
1605
align 4
1606
buf_flood_fill_recurs_0:
1607
	call get_pixel_24
1608
	cmp eax,0xffffffff ;if error coords
1609
	je .end_fun
1610
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1611
	je .end_fun
1612
 
1613
		call draw_pixel
1614
 
1615
		dec ebx
1616
		call get_pixel_24
1617
		cmp eax,esi
1618
		je @f
1619
			call buf_flood_fill_recurs_0
1620
		@@:
1621
		inc ebx
1622
 
1623
 
1624
		inc ebx
1625
		call get_pixel_24
1626
		cmp eax,esi
1627
		je @f
1628
			call buf_flood_fill_recurs_0
1629
		@@:
1630
		dec ebx
1631
 
1632
		dec ecx
1633
		call get_pixel_24
1634
		cmp eax,esi
1635
		je @f
1636
			call buf_flood_fill_recurs_0
1637
		@@:
1638
		inc ecx
1639
 
1640
		inc ecx
1641
		call get_pixel_24
1642
		cmp eax,esi
1643
		je @f
1644
			call buf_flood_fill_recurs_0
1645
		@@:
1646
		dec ecx
1647
 
1648
	.end_fun:
1649
	ret
1650
 
1651
;input:
1652
; ebx = coord_x
1653
; ecx = coord_y
1654
; edx = цвет заливки
1655
; esi = цвет пикселей, по которым будет ити заливка
1656
; edi = buf_struc
1657
;output:
1658
; eax = портится
1659
align 4
1660
buf_flood_fill_recurs_1:
1661
	call get_pixel_24
1662
	cmp eax,0xffffffff ;if error coords
1663
	je .end_fun
1664
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1665
	je .end_fun
1666
	cmp eax,esi ;если цвет пикселя не совпал с заливаемым цветом заливки, то прекращаем заливку
1667
	jne .end_fun
1668
 
1669
		call draw_pixel
1670
 
1671
		dec ebx
1672
		call get_pixel_24
1673
		cmp eax,esi
1674
		jne @f
1675
			call buf_flood_fill_recurs_1
1676
		@@:
1677
		inc ebx
1678
 
1679
 
1680
		inc ebx
1681
		call get_pixel_24
1682
		cmp eax,esi
1683
		jne @f
1684
			call buf_flood_fill_recurs_1
1685
		@@:
1686
		dec ebx
1687
 
1688
		dec ecx
1689
		call get_pixel_24
1690
		cmp eax,esi
1691
		jne @f
1692
			call buf_flood_fill_recurs_1
1693
		@@:
1694
		inc ecx
1695
 
1696
		inc ecx
1697
		call get_pixel_24
1698
		cmp eax,esi
1699
		jne @f
1700
			call buf_flood_fill_recurs_1
1701
		@@:
1702
		dec ecx
1703
 
1704
	.end_fun:
1705
	ret
1706
 
1910 IgorA 1707
;функция для рисования точки
1684 IgorA 1708
align 4
2658 IgorA 1709
proc buf_set_pixel uses ebx ecx edx edi, buf_struc:dword, coord_x:dword, coord_y:dword, color:dword
1710
	mov edi,dword[buf_struc]
1711
	mov ebx,dword[coord_x]
1712
	mov ecx,dword[coord_y]
1713
	mov edx,dword[color]
1714
	call draw_pixel
1910 IgorA 1715
	ret
1716
endp
1717
 
2658 IgorA 1718
;output:
1719
; eax = цвет точки
1720
; в случае ошибки eax = 0xffffffff
1910 IgorA 1721
align 4
2658 IgorA 1722
proc buf_get_pixel uses ebx ecx edi, buf_struc:dword, coord_x:dword, coord_y:dword
1723
	mov edi,dword[buf_struc]
1724
	mov ebx,[coord_x]
1725
	mov ecx,[coord_y]
1726
 
1727
	cmp buf2d_bits,8
1728
	jne @f
1729
		call get_pixel_8
1730
		jmp .end_fun
1731
	@@:
1732
	cmp buf2d_bits,24
1733
	jne @f
1734
		call get_pixel_24
1735
		jmp .end_fun
1736
	@@:
1737
	cmp buf2d_bits,32
1738
	jne @f
1739
		call get_pixel_32
1740
		;jmp .end_fun
1741
	@@:
1742
	.end_fun:
1743
	ret
1744
endp
1745
 
1746
align 4
1535 IgorA 1747
proc buf_img_wdiv2, buf_struc:dword
1748
	pushad
1749
	mov edi,dword[buf_struc]
1750
	cmp buf2d_bits,24
1751
	jne .end_draw_24
1752
		mov eax,buf2d_w
1753
		mov ecx,buf2d_h
1754
		imul ecx,eax
1755
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
1756
	.end_draw_24:
1757
	popad
1758
	ret
1759
endp
1760
 
1761
;input:
1762
;data_rgb - pointer to rgb data
1763
;size - count img pixels (size img data / 3(rgb) )
1764
align 4
1765
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
1766
  ;push eax ebx ecx edx
1767
  mov eax,dword[data_rgb]
1768
  mov ecx,dword[size] ;ecx = size
1769
  lea ecx,[ecx+ecx*2]
1770
  cld
1771
  @@: ;затемнение цвета пикселей
1538 IgorA 1772
		shr byte[eax],1
1773
		inc eax
1774
		loop @b
1535 IgorA 1775
 
1776
  mov eax,dword[data_rgb]
1777
  mov ecx,dword[size] ;ecx = size
1778
  shr ecx,1
1779
  @@: ;сложение цветов пикселей
1538 IgorA 1780
		mov bx,word[eax+3] ;копируем цвет соседнего пикселя
1781
		add word[eax],bx
1782
		mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
1783
		add byte[eax+2],bl
1784
		add eax,6 ;=2*3
1785
		loop @b
1535 IgorA 1786
 
1787
  mov eax,dword[data_rgb]
1788
  add eax,3
1789
  mov ebx,eax
1790
  add ebx,3
1791
  mov ecx,dword[size] ;ecx = size
1792
  shr ecx,1
1793
  dec ecx ;лишний пиксель
1794
  @@: ;поджатие пикселей
1538 IgorA 1795
		mov edx,dword[ebx]
1796
		mov word[eax],dx
1797
		shr edx,16
1798
		mov byte[eax+2],dl
1535 IgorA 1799
 
1538 IgorA 1800
		add eax,3
1801
		add ebx,6
1802
		loop @b
1535 IgorA 1803
  ;pop edx ecx ebx eax
1804
  ret
1805
endp
1806
 
1807
align 4
1808
proc buf_img_hdiv2, buf_struc:dword
1809
	pushad
1810
	mov edi,dword[buf_struc]
1811
	cmp buf2d_bits,24
1812
	jne .end_draw_24
1813
		mov eax,buf2d_w
1814
		mov ecx,buf2d_h
1815
		imul ecx,eax
1816
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
1817
	.end_draw_24:
1818
	popad
1819
	ret
1820
endp
1821
 
1822
;input:
1823
;data_rgb - pointer to rgb data
1824
;size - count img pixels (size img data / 3(rgb) )
1825
;size_w - width img in pixels
1826
align 4
1827
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
1828
  ;pushad
1829
 
1830
  mov eax,dword[data_rgb] ;eax =
1831
  mov ecx,dword[size]	  ;ecx = size
1832
  lea ecx,[ecx+ecx*2]
1833
  cld
1834
  @@: ;затемнение цвета пикселей
1835
    shr byte[eax],1
1836
    inc eax
1837
    loop @b
1838
 
1839
  mov eax,dword[data_rgb] ;eax =
1840
  mov edi,dword[size_w]
1841
  lea esi,[edi+edi*2] ;esi = width*3(rgb)
1842
  mov ebx,esi
1843
  add ebx,eax
1844
  mov ecx,dword[size]  ;ecx = size
1845
  shr ecx,1
1846
  xor edi,edi
1847
  @@: ;сложение цветов пикселей
1848
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
1849
    add word[eax],dx
1850
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
1851
    add byte[eax+2],dl
1852
 
1853
    add eax,3
1854
    add ebx,3
1855
    inc edi
1856
    cmp edi,dword[size_w]
1857
    jl .old_line
1858
      add eax,esi
1859
      add ebx,esi
1860
      xor edi,edi
1861
    .old_line:
1862
    loop @b
1863
 
1864
 
1865
  mov eax,dword[data_rgb] ;eax =
1866
  add eax,esi ;esi = width*3(rgb)
1867
  mov ebx,esi
1868
  add ebx,eax
1869
  mov ecx,dword[size] ;ecx = size
1870
  shr ecx,1
1871
  sub ecx,dword[size_w] ;лишняя строка пикселей
1872
  xor edi,edi
1873
  @@: ;поджатие пикселей
1874
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
1875
    mov word[eax],dx
1876
    shr edx,16
1877
    mov byte[eax+2],dl
1878
 
1879
    add eax,3
1880
    add ebx,3
1881
    inc edi
1882
    cmp edi,dword[size_w]
1883
    jl .old_line_2
1884
      add ebx,esi
1885
      xor edi,edi
1886
    .old_line_2:
1887
    loop @b
1888
 
1889
  ;popad
1890
  ret
1891
endp
1892
 
1893
;преобразование буфера из 24-битного в 8-битный
1894
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
1895
align 4
1896
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
1897
	pushad
1898
	mov edi,dword[buf_struc]
1899
	cmp buf2d_bits,24
1900
	jne .error
1901
		mov eax,buf2d_w
1902
		mov ecx,buf2d_h
1903
		imul ecx,eax
1904
		mov esi,ecx
1905
		;ebx - память из которой копируется
1906
		;edx - память куда копируется
1907
		mov edx,buf2d_data
1908
		mov ebx,edx
1909
		cmp [spectr],3
1910
		jge @f
1911
			add ebx,[spectr]
1912
		@@:
1913
			mov al,byte[ebx]
1914
			mov byte[edx],al
1915
			add ebx,3
1916
			inc edx
1917
			loop @b
1918
		mov buf2d_bits,8
1919
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
1920
		jmp .end_conv
1921
	.error:
1922
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
1923
	.end_conv:
1924
	popad
1925
	ret
1926
endp
1927
 
1928
;преобразование буфера из 24-битного в 32-битный
1929
align 4
1930
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
1931
	pushad
1932
	mov edi,dword[buf_struc]
1933
	cmp buf2d_bits,24
1934
	jne .error1
1935
		mov ecx,buf2d_w
1936
		mov ebx,buf2d_h
1937
		imul ebx,ecx
1938
		mov ecx,ebx ;ecx = size  8 b
1939
		shl ebx,2   ;ebx = size 32 b
1940
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
1941
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1942
		mov buf2d_bits,32
1943
		mov edx,ebx ;edx = size 32 b
1944
		sub ebx,ecx ;ebx = size 24 b
1945
		mov eax,ecx
1946
		;eax - размер  8 битных данных
1947
		;ebx - размер 24 битных данных
1948
		;edx - размер 32 битных данных
1949
		add ebx,buf2d_data
1950
		add edx,buf2d_data
1951
		mov edi,dword[buf_str8]
1952
		cmp buf2d_bits,8
1953
		jne .error2
1954
		add eax,buf2d_data
1955
		mov edi,edx
1956
		;eax - указатель на конец  8 битных данных
1957
		;ebx - указатель на конец 24 битных данных
1958
		;edi - указатель на конец 32 битных данных
1959
		@@:
1960
			sub edi,4 ;отнимаем в начале цикла,
1961
			sub ebx,3 ; потому, что указатели стоят
1962
			dec eax   ; за пределами буферов
1963
			mov edx,dword[ebx]
1964
			mov dword[edi],edx
1965
			mov dl,byte[eax]
1966
			mov byte[edi+3],dl
1967
			loop @b
1968
 
1969
		jmp .end_conv
1970
	.error1:
1971
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
1972
		jmp .end_conv
1973
	.error2:
1974
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
1975
	.end_conv:
1976
	popad
1977
	ret
1978
endp
1979
 
1980
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
1981
; указываются координаты вставки буфера buf_source относительно buf_destination
1982
; прозрачность при копировании не учитывается
1983
align 4
1984
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
1985
	locals
1986
		right_bytes dd ?
1987
	endl
1988
	pushad
1989
 
1990
	mov edi,[buf_source]
1991
	cmp buf2d_bits,24
1992
	je .sou24
1993
	cmp buf2d_bits,32
1994
	je .sou32
1995
		jmp .copy_end ;формат буфера не поодерживается
1996
 
1648 IgorA 1997
	.sou24: ;в источнике 24 битная картинка
1535 IgorA 1998
	mov eax,buf2d_w
1999
	mov edx,buf2d_h ;высота копируемой картинки
2000
	mov esi,buf2d_data ;данные копируемой картинки
2001
 
2002
	mov edi,[buf_destination]
2003
	cmp buf2d_bits,24
2004
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2005
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2006
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2007
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2008
		mov ebx,buf2d_h ;ebx - высота основного буфера
2009
		mov ecx,[coord_y]
2422 IgorA 2010
		cmp ecx,0
2011
		jge @f
2012
			;если координата coord_y<0 (1-я настройка)
2013
			add edx,ecx ;уменьшаем высоту копируемой картинки
2014
			cmp edx,0
2015
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2016
			neg ecx
2017
			;inc ecx
2018
			imul ecx,eax
2019
			lea ecx,[ecx+ecx*2] ;по 3 байта на пиксель
2020
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2021
			xor ecx,ecx ;обнуляем координату coord_y
2022
		@@:
1535 IgorA 2023
		cmp ecx,ebx
2024
		jge .copy_end ;если координата 'y' больше высоты буфера
2025
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2026
		cmp ecx,ebx
2027
		jle @f
2028
			sub ecx,ebx
2029
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2030
		@@:
2031
		mov ebx,buf2d_w
2422 IgorA 2032
		mov ecx,[coord_y] ;ecx используем для временных целей
2033
		cmp ecx,0
2034
		jg .end_otr_c_y_24
2035
			;если координата coord_y<=0 (2-я настройка)
2036
			mov ecx,[coord_x]
2037
			jmp @f
2038
		.end_otr_c_y_24:
2039
		imul ecx,ebx
1535 IgorA 2040
		add ecx,[coord_x]
2422 IgorA 2041
		@@:
1535 IgorA 2042
		lea ecx,[ecx+ecx*2]
2043
		add ecx,buf2d_data
2044
		sub ebx,eax
2045
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2046
 
2047
	mov [right_bytes],0
2048
	mov ecx,[coord_x]
2049
	cmp ecx,ebx
2050
	jl @f
2051
		sub ecx,ebx
2052
		sub eax,ecx ;укорачиваем копируемую строку
2053
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2054
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2055
		mov [right_bytes],ecx
2056
	@@:
2057
 
2058
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
2059
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2060
 
2061
	cld
2062
	cmp [right_bytes],0
2063
	jg .copy_1
2064
	.copy_0: ;простое копирование
2065
		mov ecx,eax
2066
		rep movsb
2067
		add edi,ebx
2068
		dec edx
2069
		cmp edx,0
2070
		jg .copy_0
2071
	jmp .copy_end
2072
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2073
		mov ecx,eax
2074
		rep movsb
2075
		add edi,ebx
2076
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2077
		dec edx
2078
		cmp edx,0
2079
		jg .copy_1
2080
	jmp .copy_end
2081
 
2082
	.sou32: ;в источнике 32 битная картинка
2083
	mov eax,buf2d_w
2084
	mov edx,buf2d_h ;высота копируемой картинки
2085
	mov esi,buf2d_data ;данные копируемой картинки
2086
 
2087
	mov edi,[buf_destination]
2088
	cmp buf2d_bits,24
2089
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 2090
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2091
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2092
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2093
		mov ebx,buf2d_h ;ebx - высота основного буфера
2094
		mov ecx,[coord_y]
2422 IgorA 2095
		cmp ecx,0
2096
		jge @f
2097
			;если координата coord_y<0 (1-я настройка)
2098
			add edx,ecx ;уменьшаем высоту копируемой картинки
2099
			cmp edx,0
2100
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2101
			neg ecx
2102
			;inc ecx
2103
			imul ecx,eax
2104
			shl ecx,2 ;по 4 байта на пиксель
2105
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2106
			xor ecx,ecx ;обнуляем координату coord_y
2107
		@@:
1535 IgorA 2108
		cmp ecx,ebx
2109
		jge .copy_end ;если координата 'y' больше высоты буфера
2110
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2111
		cmp ecx,ebx
2112
		jle @f
2113
			sub ecx,ebx
2114
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2115
		@@:
2116
		mov ebx,buf2d_w
2422 IgorA 2117
		;mov ecx,ebx ;ecx используем для временных целей
2118
		;imul ecx,[coord_y]
2119
		;add ecx,[coord_x]
2120
		mov ecx,[coord_y] ;ecx используем для временных целей
2121
		cmp ecx,0
2122
		jg .end_otr_c_y_32
2123
			;если координата coord_y<=0 (2-я настройка)
2124
			mov ecx,[coord_x]
2125
			jmp @f
2126
		.end_otr_c_y_32:
2127
		imul ecx,ebx
1535 IgorA 2128
		add ecx,[coord_x]
2422 IgorA 2129
		@@:
1535 IgorA 2130
		lea ecx,[ecx+ecx*2]
2131
		add ecx,buf2d_data
2132
		sub ebx,eax
2133
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2134
 
2135
	mov [right_bytes],0
2136
	mov ecx,[coord_x]
2137
	cmp ecx,ebx
2138
	jl @f
2139
		sub ecx,ebx
2140
		sub eax,ecx ;укорачиваем копируемую строку
2141
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2142
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2143
		mov [right_bytes],ecx
2144
	@@:
2145
 
2146
	;eax - колличество пикселей в 1-й строке копируемой картинки
2147
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2148
 
2149
	cld
2150
	cmp [right_bytes],0
2151
	jg .copy_3
2152
	.copy_2: ;простое копирование
2153
		mov ecx,eax
2154
		@@:
2155
			movsw
2156
			movsb
2157
			inc esi
2158
			loop @b
2159
		add edi,ebx
2160
		dec edx
2161
		cmp edx,0
2162
		jg .copy_2
2163
	jmp .copy_end
2164
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
2165
		mov ecx,eax
2166
		@@:
2167
			movsw
2168
			movsb
2169
			inc esi
2170
			loop @b
2171
		add edi,ebx
2172
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2173
		dec edx
2174
		cmp edx,0
2175
		jg .copy_3
2176
 
2177
	.copy_end:
2178
	popad
2179
	ret
2180
endp
2181
 
2182
;input:
2183
; esi = pointer to color1 + transparent
2184
; edi = pointer to background color2
2185
;output:
2186
; [edi] = combine color
2187
align 4
2188
combine_colors:
2189
	push ax bx cx dx
2190
	mov bx,0x00ff ;---get transparent---
2748 IgorA 2191
	movzx cx,byte[esi+3] ;pro
1535 IgorA 2192
	sub bx,cx ;256-pro
1653 IgorA 2193
	;---blye---
2748 IgorA 2194
	movzx ax,byte[esi]
1535 IgorA 2195
	imul ax,bx
2748 IgorA 2196
	movzx dx,byte[edi]
1535 IgorA 2197
	imul dx,cx
2198
	add ax,dx
1653 IgorA 2199
	mov byte[edi],ah
1535 IgorA 2200
	;---green---
2748 IgorA 2201
	movzx ax,byte[esi+1]
1535 IgorA 2202
	imul ax,bx
2748 IgorA 2203
	movzx dx,byte[edi+1]
1535 IgorA 2204
	imul dx,cx
2205
	add ax,dx
2206
	mov byte[edi+1],ah
1653 IgorA 2207
	;---red---
2748 IgorA 2208
	movzx ax,byte[esi+2]
1535 IgorA 2209
	imul ax,bx
2748 IgorA 2210
	movzx dx,byte[edi+2]
1535 IgorA 2211
	imul dx,cx
2212
	add ax,dx
1653 IgorA 2213
	mov byte[edi+2],ah
1535 IgorA 2214
 
2215
	pop dx cx bx ax
2216
	ret
2217
 
2218
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
2219
; указываются координаты вставки буфера buf_source относительно buf_destination
2220
; при копировании учитывается прозрачность
2221
align 4
2222
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
2223
	locals
2224
		right_bytes dd ?
2225
	endl
2226
	pushad
2227
 
2228
	mov edi,[buf_source]
2229
	cmp buf2d_bits,32
2230
	jne .copy_end ;формат буфера не поодерживается
2231
	mov eax,buf2d_w
2232
	mov edx,buf2d_h ;высота копируемой картинки
2233
	mov esi,buf2d_data ;данные копируемой картинки
2234
 
2235
	mov edi,[buf_destination]
2236
	cmp buf2d_bits,24
2237
	jne .copy_end ;формат буфера не поодерживается
2238
		mov ebx,buf2d_h ;ebx - высота основного буфера
2239
		mov ecx,[coord_y]
2383 IgorA 2240
		cmp ecx,0
2241
		jge @f
2242
			;если координата coord_y<0 (1-я настройка)
2243
			add edx,ecx ;уменьшаем высоту копируемой картинки
2244
			cmp edx,0
2245
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2246
			neg ecx
2247
			;inc ecx
2248
			imul ecx,eax
2422 IgorA 2249
			shl ecx,2 ;по 4 байта на пиксель
2383 IgorA 2250
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2251
			xor ecx,ecx ;обнуляем координату coord_y
2252
		@@:
1535 IgorA 2253
		cmp ecx,ebx
2254
		jge .copy_end ;если координата 'y' больше высоты буфера
2255
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2256
		cmp ecx,ebx
2257
		jle @f
2258
			sub ecx,ebx
2259
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2260
		@@:
2261
		mov ebx,buf2d_w
2262
		mov ecx,ebx ;ecx используем для временных целей
2383 IgorA 2263
		cmp [coord_y],0
2264
		jg .end_otr_c_y
2265
			;если координата coord_y<=0 (2-я настройка)
2266
			mov ecx,[coord_x]
2267
			jmp @f
2268
		.end_otr_c_y:
1535 IgorA 2269
		imul ecx,[coord_y]
2270
		add ecx,[coord_x]
2383 IgorA 2271
		@@:
1535 IgorA 2272
		lea ecx,[ecx+ecx*2]
2273
		add ecx,buf2d_data
2274
		sub ebx,eax
2275
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2276
 
2277
	mov [right_bytes],0
2278
	mov ecx,[coord_x]
2279
	cmp ecx,ebx
2280
	jl @f
2281
		sub ecx,ebx
2282
		sub eax,ecx ;укорачиваем копируемую строку
2283
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2284
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
2285
		mov [right_bytes],ecx
2286
	@@:
2287
 
2288
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2658 IgorA 2289
 
1535 IgorA 2290
	cld
2291
	cmp [right_bytes],0
2292
	jg .copy_1
2293
	.copy_0: ;простое копирование
2294
		mov ecx,eax
2295
		@@:
2296
			call combine_colors
2297
			add edi,3
2298
			add esi,4
2299
			loop @b
2300
		add edi,ebx
2301
		dec edx
2302
		cmp edx,0
2303
		jg .copy_0
2304
	jmp .copy_end
2305
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2306
		mov ecx,eax
2307
		@@:
2308
			call combine_colors
2309
			add edi,3
2310
			add esi,4
2311
			loop @b
2312
		add edi,ebx
2313
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2314
		dec edx
2315
		cmp edx,0
2316
		jg .copy_1
2317
 
2318
	.copy_end:
2319
	popad
2320
	ret
2321
endp
2322
 
2323
;input:
2324
; ebx - color1
2325
; esi = pointer to transparent
2326
; edi = pointer to background color2
2327
;output:
2328
; [edi] = combine color
2329
align 4
2330
combine_colors_2:
2331
	push ax ebx cx dx si
2332
	mov cl,byte[esi] ;pro
2333
	xor ch,ch
2334
	mov si,0x00ff ;---get transparent---
2335
	sub si,cx ;256-pro
2336
 
1653 IgorA 2337
		;---blye---
2748 IgorA 2338
		movzx ax,bl
1535 IgorA 2339
		shr ebx,8
2340
		imul ax,si
2748 IgorA 2341
		movzx dx,byte[edi]
1535 IgorA 2342
		imul dx,cx
2343
		add ax,dx
1653 IgorA 2344
		mov byte[edi],ah
1535 IgorA 2345
		;---green---
2748 IgorA 2346
		movzx ax,bl
1535 IgorA 2347
		shr ebx,8
2348
		imul ax,si
2748 IgorA 2349
		movzx dx,byte[edi+1]
1535 IgorA 2350
		imul dx,cx
2351
		add ax,dx
2352
		mov byte[edi+1],ah
2353
		;---red---
2748 IgorA 2354
		movzx ax,bl
1535 IgorA 2355
		imul ax,si
2748 IgorA 2356
		movzx dx,byte[edi+2]
1535 IgorA 2357
		imul dx,cx
2358
		add ax,dx
1653 IgorA 2359
		mov byte[edi+2],ah
1535 IgorA 2360
 
2361
	pop si dx cx ebx ax
2362
	ret
2363
 
2364
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
2365
; указываются координаты вставки буфера buf_source относительно buf_destination
2366
align 4
2367
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
2368
	locals
2383 IgorA 2369
		lost_bytes dd ? ;число потерянных байтов в строке копируемого изображеня (тех что не влазят в буфер)
1535 IgorA 2370
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
2371
	endl
2372
	pushad
2373
 
2374
	mov edi,[buf_source]
2375
	cmp buf2d_bits,8
2376
	jne .error1 ;формат буфера не поодерживается
2383 IgorA 2377
	mov eax,buf2d_w ;ширина копируемой картинки
1535 IgorA 2378
	mov edx,buf2d_h ;высота копируемой картинки
2379
	mov esi,buf2d_data ;данные копируемой картинки
2380
 
2381
	mov edi,[buf_destination]
2382
	cmp buf2d_bits,24
2383
	jne .error2 ;формат буфера не поодерживается
1642 IgorA 2384
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
2385
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
2422 IgorA 2386
	jge .copy_end	  ;если изображение полностью вылазит за правую сторону
1535 IgorA 2387
		mov ebx,buf2d_h ;ebx - высота основного буфера
2388
		mov ecx,[coord_y]
2367 IgorA 2389
		cmp ecx,0
2390
		jge @f
2391
			;если координата coord_y<0 (1-я настройка)
2392
			add edx,ecx ;уменьшаем высоту копируемой картинки
2383 IgorA 2393
			cmp edx,0
2394
			jle .copy_end ;если копируемое изображение находится полностью над верхней границей буфера (coord_y<0 и |coord_y|>buf_source.h)
2367 IgorA 2395
			neg ecx
2396
			;inc ecx
2397
			imul ecx,eax
2398
			add esi,ecx ;сдвигаем указатель с копируемыми данными, с учетом пропушеной части
2399
			xor ecx,ecx ;обнуляем координату coord_y
2400
		@@:
1535 IgorA 2401
		cmp ecx,ebx
2402
		jge .copy_end ;если координата 'y' больше высоты буфера
2403
		add ecx,edx ;ecx - нижняя координата копируемой картинки
2404
		cmp ecx,ebx
2405
		jle @f
2406
			sub ecx,ebx
2407
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
2408
		@@:
2409
		mov ebx,buf2d_w
2367 IgorA 2410
		mov ecx,[coord_y] ;ecx используем для временных целей
2411
		cmp ecx,0
2383 IgorA 2412
		jg .end_otr_c_y
2413
			;если координата coord_y<=0 (2-я настройка)
2367 IgorA 2414
			mov ecx,[coord_x]
2415
			jmp @f
2416
		.end_otr_c_y:
2417
		imul ecx,ebx
1535 IgorA 2418
		add ecx,[coord_x]
2367 IgorA 2419
		@@:
1535 IgorA 2420
		lea ecx,[ecx+ecx*2]
2383 IgorA 2421
		add ecx,buf2d_data ;buf2d_data данные основного буфера
2422
		sub ebx,eax ;ebx - ширина основного буфера минус ширина рисуемого буфера
1535 IgorA 2423
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2424
 
2383 IgorA 2425
	mov dword[lost_bytes],0
1535 IgorA 2426
	mov ecx,[coord_x]
2383 IgorA 2427
	cmp ecx,0
2428
	jge @f
2429
		neg ecx
2430
		;inc ecx
2431
		cmp eax,ecx ;eax - ширина копируемой картинки
2432
		jle .copy_end ;если копируемое изображение находится полностью за левой границей буфера (coord_x<0 и |coord_x|>buf_source.w)
2433
		add [lost_bytes],ecx
2434
		sub eax,ecx ;укорачиваем копируемую строку
2435
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2436
		add esi,ecx
2437
		lea ecx,[ecx+ecx*2]
2438
		add edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
2439
		xor ecx,ecx
2440
	@@:
1535 IgorA 2441
	cmp ecx,ebx
2383 IgorA 2442
	jle @f
1535 IgorA 2443
		sub ecx,ebx
2444
		sub eax,ecx ;укорачиваем копируемую строку
2445
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2446
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2383 IgorA 2447
		add [lost_bytes],ecx
1535 IgorA 2448
	@@:
2449
 
2450
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2451
	mov [dest_w_bytes],ebx
2452
	mov ebx,[color]
2453
 
2454
	cld
2383 IgorA 2455
	cmp dword[lost_bytes],0
1535 IgorA 2456
	jg .copy_1
2457
	.copy_0: ;простое копирование
2458
		mov ecx,eax
2459
		@@:
2460
			call combine_colors_2
2461
			add edi,3
2462
			inc esi
2463
			loop @b
2464
		add edi,[dest_w_bytes]
2465
		dec edx
2466
		cmp edx,0
2467
		jg .copy_0
2468
	jmp .copy_end
2383 IgorA 2469
	.copy_1: ;не простое копирование (картинка вылазит за левую и/или правую сторону)
1535 IgorA 2470
		mov ecx,eax
2471
		@@:
2472
			call combine_colors_2
2473
			add edi,3
2474
			inc esi
2475
			loop @b
2476
		add edi,[dest_w_bytes]
2383 IgorA 2477
		add esi,[lost_bytes] ;добавляем байты, которые вылазят за правую границу
1535 IgorA 2478
		dec edx
2479
		cmp edx,0
2480
		jg .copy_1
2481
 
2482
	jmp .copy_end
2483
	.error1:
2484
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
2485
		jmp .copy_end
2486
	.error2:
2487
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
2488
	.copy_end:
2489
	popad
2490
	ret
2491
endp
2492
 
2493
;преобразование 8-битного буфера размером 16*16 в размер 1*256 символов
2494
align 4
2495
proc buf_convert_text_matrix, buf_struc:dword
2496
	locals
2497
		tmp_mem dd ?
2498
		c1 dw ?
2499
		c2 dd ?
2500
		c3 dw ?
2501
	endl
2502
	pushad
2503
	mov edi,dword[buf_struc]
2504
	cmp buf2d_bits,8
2505
	jne .error
2506
		mov ecx,buf2d_h
2507
		mov ebx,ecx
2508
		shr ebx,4 ;предполагаем что в буфере 16 строк с символами, потому делим на 2^4
2509
		mov edx,buf2d_w
2510
		imul ecx,edx ;ecx = size  8 b
2511
		invoke mem.alloc,ecx ;выделяем временную память
2512
		mov [tmp_mem],eax ;eax - new memory
2513
 
2514
		shr edx,4 ;предполагаем что в буфере 16 колонок с символами, потому делим на 2^4
2515
		mov eax,ebx
2516
		imul ebx,edx ;вычисляем кооличество пикселей на 1 символ
2517
		;eax = bhe - высота буквы
2518
		;ebx = bwi*bhe - колличество пикселей в 1-й букве
2519
		;edx = bwi - ширина буквы
2520
		;ecx,esi,edi - используются в цикле .c_0
2521
		shr buf2d_w,4
2522
		shl buf2d_h,4 ;преобразовываем размеры буфера
2523
 
2524
		cld
2525
		mov esi,buf2d_data
2526
		mov edi,[tmp_mem]
2527
		mov word[c3],16
2528
		.c_3:
2529
			mov dword[c2],eax
2530
			.c_2:
2531
				mov word[c1],16
2532
				.c_1:
2533
					mov ecx,edx ;.c_0:
2534
					rep movsb
2535
					add edi,ebx
2536
					sub edi,edx ;edi+=(bwi*bhe-bwi)
2537
					dec word[c1]
2538
					cmp word[c1],0
2539
					jg .c_1
2540
				add edi,edx
2541
				shl ebx,4
2542
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
2543
				shr ebx,4
2544
				dec dword[c2]
2545
				cmp dword[c2],0
2546
				jg .c_2
2547
			sub edi,ebx
2548
			shl ebx,4
2549
			add edi,ebx ;edi+=(15*bwi*bhe)
2550
			shr ebx,4
2551
			dec word[c3]
2552
			cmp word[c3],0
2553
			jg .c_3
2554
 
2555
		mov edi,dword[buf_struc] ;копирование новой матрицы в основной буфер
2556
		mov edi,buf2d_data
2557
		mov esi,[tmp_mem]
2558
		mov ecx,ebx
2559
		shl ecx,8
2560
		rep movsb
2561
		invoke mem.free,[tmp_mem] ;чистим временную память
2562
		jmp .end_conv
2563
	.error:
2564
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
2565
	.end_conv:
2566
	popad
2567
	ret
2568
endp
2569
 
2570
align 4
2571
buf_s_matr buf_2d_header ? ;локальная матрица символа
2572
 
2573
align 4
2574
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
2575
	locals
2576
		buf_t_matr_offs dd ?
2577
	endl
2578
	pushad
2579
	mov edi,dword[buf_struc]
2580
	cmp buf2d_bits,24
2581
	jne .error2
2582
	mov edi,dword[buf_t_matr]
2583
	cmp buf2d_bits,8
2584
	jne .error1
2585
		mov edx,buf2d_data
2586
		mov [buf_t_matr_offs],edx
2587
		mov ecx,BUF_STRUCT_SIZE ;копируем структуру текстовой матрицы
2588
		mov esi,edi
2589
		lea edi,[buf_s_matr]
2590
		cld
2591
		rep movsb
2592
		lea edi,[buf_s_matr]
2593
		shr buf2d_h,8 ;делим высоту символьного буфера на 256, для нахождения высоты 1-го символа
2594
		mov ebx,buf2d_h ;берем высоту символа
2595
		mov ecx,buf2d_w ;берем ширину символа
2596
 
2597
		mov eax,[coord_x]
2598
		mov esi,[text]
2599
		cmp byte[esi],0
2600
		je .end_draw ;если пустая строка
2601
		@@:
2602
			xor edx,edx
2603
			mov dl,byte[esi] ;берем код символа
2604
			imul edx,ebx ;умножаем его на высоту символа
2605
			imul edx,ecx ;умножаем на ширину символа
2606
			add edx,[buf_t_matr_offs] ;прибавляем смещение 0-го символа, т. е. получается смещение выводимого символа
2607
			mov buf2d_data,edx ;в локальный буфер символа, ставим указатель на нужный символ из буфера buf_t_matr
2608
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
2609
			add eax,ecx
2610
			.new_s:
2611
				inc esi
2612
				cmp byte[esi],13
2613
				jne .no_13
2614
					mov eax,[coord_x]
2615
					add [coord_y],ebx
2616
					jmp .new_s
2617
				.no_13:
2618
			cmp byte[esi],0
2619
			jne @b
2620
		jmp .end_draw
2621
	.error1:
2622
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
2623
		jmp .end_draw
2624
	.error2:
2625
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
2626
	.end_draw:
2627
	popad
2628
	ret
2629
endp
2630
 
2631
align 4
2632
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
2633
	pushad
2634
	mov eax,63
2635
	mov ebx,1
2636
 
2637
	mov esi,[fun]
2638
	@@:
2639
		mov cl,byte[esi]
2640
		int 0x40
2641
		inc esi
2642
		cmp byte[esi],0
2643
		jne @b
2644
	mov cl,':'
2645
	int 0x40
2646
	mov cl,' '
2647
	int 0x40
2648
	mov esi,[mes]
2649
	@@:
2650
		mov cl,byte[esi]
2651
		int 0x40
2652
		inc esi
2653
		cmp byte[esi],0
2654
		jne @b
2655
	popad
2656
	ret
2657
endp
2658
 
2659
;input:
2660
; ebp+8  = p0
2661
; ebp+12 = p1
2662
align 4
2663
line_len4i:
2664
	push ebp
2665
	mov ebp,esp
2666
		finit
2667
		fild word [ebp+8]
2668
		fisub word [ebp+12]
2669
		fmul st0,st0 ;st0=x^2
2670
		fild word [ebp+10]
2671
		fisub word [ebp+14]
2672
		fmul st0,st0 ;st0=y^2
2673
		fadd st0,st1
2674
		fsqrt
2675
		fstp dword [ebp+12]
2676
	pop ebp
2677
	ret 4 ;8
2678
 
2679
align 4
1727 IgorA 2680
proc buf_curve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
1535 IgorA 2681
	locals
2682
		delt_t dd ?
2683
		opr_param dd ?
2684
		v_poi_0 dd ?
2685
	endl
2686
	pushad
2687
 
2688
;float t, xt,yt;
2689
;for(t=.0;t<1.;t+=.005){
2690
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
2691
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
2692
;  dc.SetPixel(xt,yt,255L);
2693
;}
2694
 
1727 IgorA 2695
	mov edx,[color] ;set curve color
1535 IgorA 2696
	mov edi,[buffer]
2697
	xor ebx,ebx
2698
	xor ecx,ecx
2699
 
2700
	finit
2701
 
2702
	; calculate delta t
2703
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
2704
	fadd dword[esp]
2705
	add esp,4 ;pop ...
2706
 
2707
	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
2708
	fadd dword[esp]
2709
	add esp,4 ;pop ...
2710
 
2711
	fadd st0,st0 ; len*=2
2712
	ftst
2713
	fstsw ax
2714
 
2715
	fld1
2716
	sahf
2717
	jle @f ;избегаем деления на 0
2718
		fdiv st0,st1
2719
	@@:
2720
	fstp dword[delt_t]
2721
 
2722
	finit
2723
 
2724
	;fild word[coord_p2+2] ;y2
2725
	fild word[coord_p1+2] ;y1
2726
	fild word[coord_p0+2] ;y0
2727
	fild word[coord_p2] ;x2
2728
	fild word[coord_p1] ;x1
2729
	fild word[coord_p0] ;x0
2730
	fld dword[delt_t]
2731
	fldz ;t=.0
2732
 
2733
	@@:
2734
		fld1
2735
		fsub st0,st1 ;1.-t
2736
		fmul st0,st0 ;pow(1.-t,2)
2737
		fmul st0,st3 ;...*x0
2738
		fstp dword[opr_param]
2739
 
2740
		fld1
2741
		fsub st0,st1 ;1.-t
2742
		fmul st0,st1 ;(1.-t)*t
2743
		fadd st0,st0
2744
		fmul st0,st4 ;...*x1
2745
		mov esi,dword[opr_param]
2746
		fstp dword[opr_param]
2747
 
2748
		fldz
2749
		fadd st0,st1 ;0+t
2750
		fmul st0,st0 ;t*t
2751
		fmul st0,st5 ;...*x2
2752
 
2753
		fadd dword[opr_param]
2754
		mov dword[opr_param],esi
2755
		fadd dword[opr_param]
2756
		fistp word[v_poi_0] ;x
2757
 
2758
		fld1
2759
		fsub st0,st1 ;1.-t
2760
		fmul st0,st0 ;pow(1.-t,2)
2761
		fmul st0,st6 ;...*y0
2762
		fstp dword[opr_param]
2763
 
2764
		fld1
2765
		fsub st0,st1 ;1.-t
2766
		fmul st0,st1 ;(1.-t)*t
2767
		fadd st0,st0
2768
		fmul st0,st7 ;...*y1
2769
		mov esi,dword[opr_param]
2770
		fstp dword[opr_param]
2771
 
2772
		fldz
2773
		fadd st0,st1 ;0+t
2774
		fmul st0,st0 ;t*t
2775
		fimul word[coord_p2+2] ;...*y2
2776
 
2777
		fadd dword[opr_param]
2778
		mov dword[opr_param],esi
2779
		fadd dword[opr_param]
2780
		fistp word[v_poi_0+2] ;y
2781
 
2782
		mov eax,1
2783
		mov bx,word[v_poi_0+2]
2784
		mov cx,word[v_poi_0]
2785
		call draw_pixel
2786
 
2787
		fadd st0,st1 ;t+dt
2788
 
2789
		fld1
2790
		fcomp
2791
		fstsw ax
2792
		sahf
2793
	jae @b
2794
 
2795
	popad
2796
	ret
2797
endp
2798
 
2748 IgorA 2799
 
2800
 
2801
;*** функции для работы с воксельной графикой ***
2802
 
2803
 
2804
 
2805
;создание воксельных кистей
2806
align 4
2807
proc vox_brush_create uses eax ebx ecx edi, h_br:dword, buf_z:dword
2808
	mov edi,[h_br]
2809
	movzx ecx,byte[edi+3]
2810
	add edi,4
2811
 
2812
	; *** создание единичной кисти ***
2813
	mov eax,[buf_z]
2814
	mov buf2d_data,eax
2815
	movzx eax,byte[edi-4] ;ширина единичной кисти
2816
	mov buf2d_w,eax ;ширина буфера
2817
	movzx eax,byte[edi-4+1] ;высота единичной кисти
2818
	mov buf2d_h,eax ;высота буфера
2819
	mov buf2d_size_lt,0 ;отступ слева и справа для буфера
2820
	mov buf2d_color,0 ;цвет фона буфера
2821
	mov buf2d_bits,32 ;количество бит в 1-й точке изображения
2822
 
2823
	; *** создание следующих кистей ***
2824
	cmp ecx,1
2825
	jl .end_creat
2826
	movzx ebx,byte[edi-4+2] ;высота основания единичной кисти
2827
	shr ebx,1
2828
	cld
2829
	@@:
2830
		mov eax,edi
2831
		add edi,BUF_STRUCT_SIZE
2832
		stdcall vox_create_next_brush, eax, edi, ebx
2833
		shl ebx,1
2834
		loop @b
2835
	.end_creat:
2836
	ret
2837
endp
2838
 
2839
;удаление воксельных кистей
2840
align 4
2841
proc vox_brush_delete uses ecx edi, h_br:dword
2842
	mov edi,[h_br]
2843
	movzx ecx,byte[edi+3]
2844
	add edi,4
2845
 
2846
	; *** удаление кистей ***
2847
	cmp ecx,1
2848
	jl .end_delete
2849
	cld
2850
	@@:
2851
		add edi,BUF_STRUCT_SIZE
2852
		stdcall buf_delete, edi
2853
		loop @b
2854
	.end_delete:
2855
	ret
2856
endp
2857
 
2858
;функция для создания вокселя следующего порядка
2859
; buf_v1 - буфер с исходным вокселем
2860
; buf_v2 - буфер с увеличеным вокселем
2861
; h - высота основания исходного вокселя : 2
2862
align 4
2863
proc vox_create_next_brush uses eax ebx ecx edx edi, buf_v1:dword, buf_v2:dword, h:dword
2864
	mov edi,[buf_v1]
2865
	mov ebx,buf2d_h
2866
	mov ecx,buf2d_w
2867
	mov edi,[buf_v2]
2868
	mov buf2d_h,ebx
2869
	shl buf2d_h,1
2870
	mov buf2d_w,ecx
2871
	shl buf2d_w,1
2872
	mov buf2d_color,0
2873
	mov buf2d_bits,32
2874
 
2875
	stdcall buf_create, [buf_v2] ;создание буфера глубины
2876
	shr ecx,1
2877
	mov edx,[h]
2878
	shl edx,1
2879
	sub ebx,edx
2880
	;ecx - ширина исходного вокселя : 2
2881
	;ebx - высота исходного вокселя (без основания)
2882
	;edx - высота основания исходного вокселя
2883
	stdcall vox_add, [buf_v2], [buf_v1], ecx,0,0
2884
	stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,0
2885
 
2886
	mov eax,[h]
2887
	stdcall vox_add, [buf_v2], [buf_v1], 0,eax,eax
2888
	push eax ;stdcall ...
2889
	add eax,ebx
2890
	stdcall vox_add, [buf_v2], [buf_v1], 0,eax ;,...
2891
	sub eax,ebx
2892
 
2893
	shl ecx,1
2894
	;ecx - ширина исходного вокселя
2895
	mov eax,[h]
2896
	stdcall vox_add, [buf_v2], [buf_v1], ecx,eax,eax
2897
	push eax ;stdcall ...,[h]
2898
	add eax,ebx
2899
	stdcall vox_add, [buf_v2], [buf_v1], ecx,eax;,[h]
2900
	;sub eax,ebx
2901
	shr ecx,1
2902
 
2903
	;ecx - ширина исходного вокселя : 2
2904
	stdcall vox_add, [buf_v2], [buf_v1], ecx,edx,edx
2905
	add ebx,edx
2906
	stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,edx
2907
 
2908
	ret
2909
endp
2910
 
2911
;
2912
align 4
2913
proc vox_add uses ebx ecx, buf_v1:dword, buf_v2:dword, coord_x:dword, coord_y:dword, coord_z:dword
2914
pushad
2915
	mov eax,[coord_x]
2916
	mov ebx,[coord_y]
2917
	mov edi,[buf_v2]
2918
	mov ecx,buf2d_h
2919
	mov esi,buf2d_w
2920
	imul ecx,esi
2921
	add esi,eax
2922
	mov edx,buf2d_data
2923
	cld
2924
	;ecx - count pixels in voxel
2925
	;edx - указатель на данные в воксельном буфере
2926
	;edi - указатель на воксельный буфер
2927
	;esi - width voxel buffer add coord x
2928
	.cycle:
2929
		cmp dword[edx],0
2930
		je @f
2931
			;проверяем буфер глубины
2932
			push eax ecx esi
2933
			mov ecx,eax
2934
			stdcall buf_get_pixel, [buf_v1],ecx,ebx
2935
			mov esi,[edx]
2936
			add esi,[coord_z]
2937
			cmp eax,esi
2938
			jge .end_draw
2939
			stdcall buf_set_pixel, [buf_v1],ecx,ebx,esi ;esi = new coord z
2940
			.end_draw:
2941
			pop esi ecx eax
2942
		@@:
2943
		add edx,4
2944
		inc eax
2945
		cmp eax,esi
2946
		jl @f
2947
			inc ebx
2948
			sub eax,buf2d_w
2949
		@@:
2950
		loop .cycle
2951
popad
2952
	ret
2953
endp
2954
 
1535 IgorA 2955
txt_err_n8b db 'need buffer 8 bit',13,10,0
2956
txt_err_n24b db 'need buffer 24 bit',13,10,0
2358 IgorA 2957
txt_err_n8_24b db 'need buffer 8 or 24 bit',13,10,0
1535 IgorA 2958
 
2959
align 16
2960
EXPORTS:
2961
	dd sz_lib_init, lib_init
2962
	dd sz_buf2d_create, buf_create
2963
	dd sz_buf2d_create_f_img, buf_create_f_img
2964
	dd sz_buf2d_clear, buf_clear
2965
	dd sz_buf2d_draw, buf_draw_buf
2966
	dd sz_buf2d_delete, buf_delete
2136 IgorA 2967
	dd sz_buf2d_resize, buf_resize
1535 IgorA 2968
	dd sz_buf2d_line, buf_line_brs
2230 IgorA 2969
	dd sz_buf2d_line_sm, buf_line_brs_sm
1634 IgorA 2970
	dd sz_buf2d_rect_by_size, buf_rect_by_size
1642 IgorA 2971
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
1535 IgorA 2972
	dd sz_buf2d_circle, buf_circle
2973
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
2974
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
2975
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
2976
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
2977
	dd sz_buf2d_bit_blt, buf_bit_blt
2978
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
2979
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1727 IgorA 2980
	dd sz_buf2d_curve_bezier, buf_curve_bezier
1535 IgorA 2981
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
2982
	dd sz_buf2d_draw_text, buf_draw_text
2983
	dd sz_buf2d_crop_color, buf_crop_color
2984
	dd sz_buf2d_offset_h, buf_offset_h
1684 IgorA 2985
	dd sz_buf2d_flood_fill, buf_flood_fill
1910 IgorA 2986
	dd sz_buf2d_set_pixel, buf_set_pixel
2658 IgorA 2987
	dd sz_buf2d_get_pixel, buf_get_pixel
2748 IgorA 2988
	dd sz_buf2d_vox_brush_create, vox_brush_create
2989
	dd sz_buf2d_vox_brush_delete, vox_brush_delete
1535 IgorA 2990
	dd 0,0
2991
	sz_lib_init db 'lib_init',0
2992
	sz_buf2d_create db 'buf2d_create',0
2993
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
2994
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
2995
	sz_buf2d_draw db 'buf2d_draw',0
2996
	sz_buf2d_delete db 'buf2d_delete',0
2136 IgorA 2997
	sz_buf2d_resize db 'buf2d_resize',0
1535 IgorA 2998
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
2230 IgorA 2999
	sz_buf2d_line_sm db 'buf2d_line_sm',0 ;рисование сглаженной линии
1642 IgorA 3000
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;рисование рамки прямоугольника, 2-я координата задана по размеру
3001
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;рисование залитого прямоугольника, 2-я координата задана по размеру
1535 IgorA 3002
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
3003
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
3004
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
3005
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
3006
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
3007
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
3008
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
3009
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1727 IgorA 3010
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
1535 IgorA 3011
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
3012
	sz_buf2d_draw_text db 'buf2d_draw_text',0
3013
	sz_buf2d_crop_color db 'buf2d_crop_color',0
3014
	sz_buf2d_offset_h db 'buf2d_offset_h',0
1684 IgorA 3015
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
1910 IgorA 3016
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
2658 IgorA 3017
	sz_buf2d_get_pixel db 'buf2d_get_pixel',0
2748 IgorA 3018
	sz_buf2d_vox_brush_create db 'buf2d_vox_brush_create',0
3019
	sz_buf2d_vox_brush_delete db 'buf2d_vox_brush_delete',0