Subversion Repositories Kolibri OS

Rev

Rev 1538 | Go to most recent revision | Details | 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] ;высота буфера
18
buf2d_t equ word[edi+6] ;отступ сверху
19
buf2d_size_lt equ dword[edi+4] ;отступ слева и справа для буфера
20
buf2d_color equ dword[edi+16] ;цвет фона буфера
21
buf2d_bits equ byte[edi+20] ;количество бит в 1-й точке изображения
22
 
23
struct buf_2d_header
24
	img_data dd ?
25
	left dw ? ;+4 left
26
	top dw ? ;+6 top
27
	size_x dd ? ;+8 w
28
	size_y dd ? ;+12 h
29
	color dd ? ;+16 color
30
	bit_pp db ? ;+21 bit in pixel
31
ends
32
 
33
macro swap v1, v2 {
34
  push v1
35
  push v2
36
  pop v1
37
  pop v2
38
}
39
 
40
;флаги, для функции обрезания буфера
41
BUF2D_OPT_CROP_TOP equ 1 ;обрезка сверху
42
BUF2D_OPT_CROP_LEFT equ 2 ;обрезка слева
43
BUF2D_OPT_CROP_BOTTOM equ 4 ;обрезка снизу
44
BUF2D_OPT_CROP_RIGHT equ 8 ;обрезка справа
45
BUF2D_BIT_OPT_CROP_TOP equ 0
46
BUF2D_BIT_OPT_CROP_LEFT equ 1
47
BUF2D_BIT_OPT_CROP_BOTTOM equ 2
48
BUF2D_BIT_OPT_CROP_RIGHT equ 3
49
 
50
;input:
51
; eax = указатель на функцию выделения памяти
52
; ebx = ... освобождения памяти
53
; ecx = ... перераспределения памяти
54
; edx = ... загрузки библиотеки (пока не используется)
55
align 16
56
lib_init:
57
	mov dword[mem.alloc], eax
58
	mov dword[mem.free], ebx
59
	mov dword[mem.realloc], ecx
60
	mov dword[dll.load], edx
61
	ret
62
 
63
;input:
64
; ebx = coord x
65
; ecx = coord y
66
; edx = pixel color
67
; edi = pointer to buffer struct
68
align 4
69
draw_pixel:
70
	;cmp buf2d_bits,24
71
	;jne @f
72
	bt ebx,31
73
	jc @f
74
	bt ecx,31
75
	jc @f
76
	cmp ebx,buf2d_w
77
	jge @f
78
	cmp ecx,buf2d_h
79
	jge @f
80
	push esi
81
		mov esi,buf2d_w ;size x
82
		imul esi,ecx ;size_x*y
83
		add esi,ebx	 ;size_x*y+x
84
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
85
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
86
 
87
		mov word[esi],dx ;copy pixel color
88
		ror edx,16
89
		mov byte[esi+2],dl
90
		ror edx,16
91
	pop esi
92
	@@:
93
	ret
94
;endp
95
 
96
;создание буфера
97
align 4
98
proc buf_create, buf_struc:dword
99
	pushad
100
	mov edi,dword[buf_struc]
101
	mov ecx,buf2d_w
102
	mov ebx,buf2d_h
103
	imul ecx,ebx
104
	cmp buf2d_bits,24
105
	jne @f
106
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
107
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
108
	@@:
109
	cmp buf2d_bits,32
110
	jne @f
111
		shl ecx,2 ; 32 bit = 4
112
	@@:
113
	invoke mem.alloc,ecx
114
	mov buf2d_data,eax
115
 
116
	stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
117
	popad
118
	ret
119
endp
120
 
121
;создание буфера на основе изображения rgb
122
align 4
123
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
124
	pushad
125
	mov edi,dword[buf_struc]
126
	mov ecx,buf2d_w
127
	mov ebx,buf2d_h
128
	imul ecx,ebx
129
	cmp buf2d_bits,24
130
	jne @f
131
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
132
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
133
	@@:
134
	cmp buf2d_bits,32
135
	jne @f
136
		shl ecx,2 ; 32 bit = 4
137
	@@:
138
	invoke mem.alloc,ecx
139
	mov buf2d_data,eax
140
 
141
	cmp buf2d_bits,24
142
	jne @f
143
		cld
144
		mov esi,[rgb_data]
145
		mov edi,eax ;eax=buf2d_data
146
		rep movsb ;копируем биты изображения в буфер
147
		jmp .end_create
148
	@@:
149
		stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
150
	.end_create:
151
	popad
152
	ret
153
endp
154
 
155
align 4
156
proc buf_clear, buf_struc:dword, color:dword ;очистка буфера заданым цветом
157
	pushad
158
	mov edi,dword[buf_struc]
159
 
160
	mov ecx,buf2d_w
161
	mov ebx,buf2d_h
162
	imul ecx,ebx
163
 
164
	cld
165
 
166
	cmp buf2d_bits,8
167
	jne .end_clear_8
168
		mov edi,buf2d_data
169
		mov al,byte[color]
170
		rep stosb
171
		jmp .end_clear_32
172
	.end_clear_8:
173
 
174
	cmp buf2d_bits,24
175
	jne .end_clear_24
176
		mov edi,buf2d_data
177
		mov eax,dword[color]
178
		mov ebx,eax
179
		shr ebx,16
180
		@@:
181
			stosw
182
			mov byte[edi],bl
183
			inc edi
184
			loop @b
185
		jmp .end_clear_32
186
	.end_clear_24:
187
 
188
	cmp buf2d_bits,32
189
	jne .end_clear_32
190
		mov edi,buf2d_data
191
		mov eax,dword[color]
192
		rep stosd
193
		;jmp .end_clear_32
194
	.end_clear_32:
195
	popad
196
	ret
197
endp
198
 
199
align 4
200
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword ;обрезка буфера по заданому цветом цвету
201
locals
202
	crop_r dd ?
203
endl
204
	pushad
205
	mov edi,dword[buf_struc]
206
	cmp buf2d_bits,24
207
	jne .24end_f
208
 
209
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
210
	jae .24no_crop_bottom
211
		mov eax,dword[color]
212
		mov edx,eax ;ax = colors - r,g
213
		shr edx,16 ;dl = color - b
214
		mov ecx,buf2d_h
215
		mov ebx,buf2d_w
216
		imul ecx,ebx
217
		lea esi,[ecx+ecx*2] ;esi=3*ecx
218
		add esi,buf2d_data
219
		cld
220
		@@:
221
			sub esi,3
222
			cmp word[esi],ax
223
			jne @f
224
			cmp byte[esi+2],dl
225
			jne @f
226
			loop @b
227
		@@:
228
		lea ebx,[ebx+ebx*2]
229
		xor edx,edx
230
		mov eax,buf2d_h
231
		imul eax,ebx
232
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
233
		@@:
234
			add esi,ebx
235
			cmp esi,eax
236
			jge @f
237
			inc edx ;вычисляем число полных строк для обрезания
238
			loop @b
239
		@@:
240
		cmp edx,0
241
		je .24no_crop_bottom
242
			cmp edx,buf2d_h
243
			jge .24no_crop_bottom ;что-бы не получить пустой буфер
244
			sub buf2d_h,edx ;уменьшаем высоту буфера
245
			mov ecx,buf2d_h
246
			imul ecx,ebx ;ecx = новый размер изображения
247
			invoke mem.realloc,buf2d_data,ecx
248
			mov buf2d_data,eax ;на случай если изменился указатель на данные
249
	.24no_crop_bottom:
250
 
251
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
252
	jae .24no_crop_top
253
		mov eax,dword[color]
254
		mov edx,eax ;ax = colors - r,g
255
		shr edx,16 ;dl = color - b
256
		mov esi,buf2d_data
257
		mov ecx,buf2d_h
258
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
259
		mov ebx,buf2d_w
260
		imul ecx,ebx
261
		cld
262
		@@:
263
			cmp word[esi],ax
264
			jne @f
265
			cmp byte[esi+2],dl
266
			jne @f
267
			add esi,3
268
			loop @b
269
		@@:
270
		lea ebx,[ebx+ebx*2]
271
		xor edx,edx
272
		@@:
273
			sub esi,ebx
274
			cmp esi,buf2d_data
275
			jl @f
276
			inc edx ;вычисляем число полных строк для обрезания
277
			loop @b
278
		@@:
279
		cmp edx,0
280
		je .24no_crop_top
281
			xor eax,eax
282
			sub eax,edx
283
			mov ebx,buf2d_h
284
			sub ebx,edx
285
			stdcall buf_offset_h, edi, eax, edx, ebx ;сдвигаем изображение в буфере вверх (eax<0)
286
			sub buf2d_h,edx ;уменьшаем высоту буфера
287
			mov ecx,buf2d_h
288
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
289
			mov ebx,buf2d_w
290
			imul ecx,ebx
291
			lea ecx,[ecx+ecx*2]
292
			invoke mem.realloc,buf2d_data,ecx
293
			mov buf2d_data,eax ;на случай если изменился указатель на данные
294
	.24no_crop_top:
295
 
296
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
297
	jae .24no_crop_right
298
		mov eax,dword[color]
299
		mov edx,eax ;ax = colors - r,g
300
		shr edx,16 ;dl = color - b
301
		mov ebx,buf2d_w
302
		lea ebx,[ebx+ebx*2]
303
		mov esi,ebx
304
		imul esi,buf2d_h
305
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
306
		mov dword[crop_r],0
307
		cld
308
		.found_beg:
309
		sub esi,3 ;двигаемся на 1-ну колонку влево
310
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
311
		@@:
312
			cmp word[esi],ax
313
			jne .found
314
			cmp byte[esi+2],dl
315
			jne .found
316
			sub esi,ebx ;прыгаем на верхнюю строку
317
			loop @b
318
		inc dword[crop_r]
319
 
320
		mov ecx,buf2d_w
321
		dec ecx ;1 колонка на запас
322
		cmp dword[crop_r],ecx
323
		jge .found
324
 
325
		sub esi,3 ;двигаемся на 1-ну колонку влево
326
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
327
		@@:
328
			add esi,ebx ;прыгаем на нижнюю строку
329
			cmp word[esi],ax
330
			jne .found
331
			cmp byte[esi+2],dl
332
			jne .found
333
			loop @b
334
		inc dword[crop_r]
335
 
336
		mov ecx,buf2d_w
337
		dec ecx ;1 колонка на запас
338
		cmp dword[crop_r],ecx
339
		jl .found_beg
340
 
341
		.found:
342
		cmp dword[crop_r],0
343
		je .24no_crop_right
344
			mov ecx,buf2d_w
345
			sub ecx,dword[crop_r]
346
			stdcall img_rgb_wcrop, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
347
			mov buf2d_w,ecx ;ставим новую ширину для буфера
348
			mov ebx,buf2d_h
349
			imul ecx,ebx
350
			lea ecx,[ecx+ecx*2]
351
			invoke mem.realloc,buf2d_data,ecx
352
			mov buf2d_data,eax ;на случай если изменился указатель на данные
353
	.24no_crop_right:
354
 
355
	.24end_f:
356
 
357
 
358
	cmp buf2d_bits,8
359
	jne .8end_f
360
 
361
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
362
	jae .8no_crop_bottom
363
		mov eax,dword[color]
364
		mov esi,buf2d_data
365
		mov ecx,buf2d_h
366
		mov ebx,buf2d_w
367
		imul ecx,ebx
368
		mov esi,ecx
369
		add esi,buf2d_data
370
		cld
371
		@@:
372
			dec esi
373
			cmp byte[esi],al
374
			jne @f
375
			loop @b
376
		@@:
377
		xor edx,edx
378
		mov eax,buf2d_h
379
		imul eax,ebx
380
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
381
		@@:
382
			add esi,ebx
383
			cmp esi,eax
384
			jge @f
385
			inc edx
386
			loop @b
387
		@@:
388
		cmp edx,0
389
		je .8no_crop_bottom
390
			cmp edx,buf2d_h
391
			jge .8no_crop_bottom ;что-бы не получить пустой буфер
392
			sub buf2d_h,edx ;уменьшаем высоту буфера
393
			mov ecx,buf2d_h
394
			imul ecx,ebx ;ecx = новый размер изображения
395
			invoke mem.realloc,buf2d_data,ecx
396
			mov buf2d_data,eax ;на случай если изменился указатель на данные
397
	.8no_crop_bottom:
398
 
399
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
400
	jae .8no_crop_top
401
		mov eax,dword[color]
402
		mov esi,buf2d_data
403
		mov ecx,buf2d_h
404
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
405
		mov ebx,buf2d_w
406
		imul ecx,ebx
407
		cld
408
		@@:
409
			cmp byte[esi],al
410
			jne @f
411
			inc esi
412
			loop @b
413
		@@:
414
		xor edx,edx
415
		@@:
416
			sub esi,ebx
417
			cmp esi,buf2d_data
418
			jl @f
419
			inc edx
420
			loop @b
421
		@@:
422
		cmp edx,0
423
		je .8no_crop_top
424
			xor eax,eax
425
			sub eax,edx
426
			mov ebx,buf2d_h
427
			sub ebx,edx
428
			stdcall buf_offset_h, edi, eax, edx, ebx
429
			mov ecx,buf2d_h
430
			sub ecx,edx
431
			mov buf2d_h,ecx ;уменьшаем высоту буфера
432
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
433
			mov ebx,buf2d_w
434
			imul ecx,ebx
435
			invoke mem.realloc,buf2d_data,ecx
436
			mov buf2d_data,eax ;на случай если изменился указатель на данные
437
	.8no_crop_top:
438
 
439
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
440
	jae .8no_crop_right
441
		mov eax,dword[color]
442
		mov ebx,buf2d_w
443
		mov esi,ebx
444
		imul esi,buf2d_h
445
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
446
		xor edx,edx
447
		cld
448
 
449
		.8found_beg:
450
		dec esi ;двигаемся на 1-ну колонку влево
451
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
452
		@@:
453
			cmp byte[esi],al
454
			jne .8found
455
			sub esi,ebx ;прыгаем на верхнюю строку
456
			loop @b
457
		inc edx
458
		mov ecx,buf2d_w
459
		dec ecx ;1 колонка на запас
460
		cmp edx,ecx
461
		jge .8found
462
 
463
		dec esi ;двигаемся на 1-ну колонку влево
464
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
465
		@@:
466
			add esi,ebx ;прыгаем на нижнюю строку
467
			cmp byte[esi],al
468
			jne .8found
469
			loop @b
470
		inc edx
471
 
472
		mov ecx,buf2d_w
473
		dec ecx ;1 колонка на запас
474
		cmp edx,ecx
475
		jl .8found_beg
476
 
477
		.8found:
478
		cmp edx,0
479
		je .8no_crop_right
480
			mov ecx,buf2d_w
481
			sub ecx,edx
482
			stdcall img_gray_wcrop, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
483
			mov buf2d_w,ecx ;ставим новую ширину для буфера
484
			mov ebx,buf2d_h
485
			imul ecx,ebx
486
			invoke mem.realloc,buf2d_data,ecx
487
			mov buf2d_data,eax ;на случай если изменился указатель на данные
488
	.8no_crop_right:
489
 
490
	.8end_f:
491
 
492
	popad
493
	ret
494
endp
495
 
496
;input:
497
;data_rgb - pointer to rgb data
498
;size_w_old - width img in pixels
499
;size_w_new - new width img in pixels
500
;size_h - height img in pixels
501
align 4
502
proc img_rgb_wcrop, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
503
	pushad
504
	mov eax, dword[size_w_old]
505
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
506
	mov ebx, dword[size_w_new]
507
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
508
	mov edx, dword[size_h]
509
	mov edi, dword[data_rgb] ;edi - получает данные
510
	mov esi, edi
511
	add edi, ebx
512
	add esi, eax
513
	cld
514
	@@:
515
		dec edx ;уменьшаем счетчик оставшихся строк на 1
516
		cmp edx,0
517
		jle @f
518
		mov ecx, ebx
519
		rep movsb ;перенос (копирование) строки пикселей
520
		add esi,eax ;переход на новую строчку изображения
521
		sub esi,ebx
522
		jmp @b
523
	@@:
524
	popad
525
	ret
526
endp
527
 
528
;input:
529
;data_gray - pointer to gray data
530
;size_w_old - width img in pixels
531
;size_w_new - new width img in pixels
532
;size_h - height img in pixels
533
align 4
534
proc img_gray_wcrop, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
535
	pushad
536
	mov eax, dword[size_w_old]
537
	mov ebx, dword[size_w_new]
538
	mov edx, dword[size_h]
539
	mov edi, dword[data_gray] ;edi - получает данные
540
	mov esi, edi
541
	add edi, ebx
542
	add esi, eax
543
	cld
544
	@@:
545
		dec edx ;уменьшаем счетчик оставшихся строк на 1
546
		cmp edx,0
547
		jle @f
548
		mov ecx, ebx
549
		rep movsb ;перенос (копирование) строки пикселей
550
		add esi,eax ;переход на новую строчку изображения
551
		sub esi,ebx
552
		jmp @b
553
	@@:
554
	popad
555
	ret
556
endp
557
 
558
;hoffs - колличество пикселей на котрые поднимается/опускается изображение
559
;img_t - высота, с которой начинается двигающаяся часть изображения
560
align 4
561
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;сдвигает изображение по высоте
562
	pushad
563
	mov edi,dword[buf_struc]
564
	cmp buf2d_bits,24
565
	jne .end_move_24
566
 
567
	mov eax,[hoffs]
568
	cmp eax,0
569
	je .end_move_24
570
		mov ebx,buf2d_w
571
		mov edx,dword[img_t]
572
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
573
			cmp ecx,buf2d_h
574
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
575
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
576
			lea ecx,[ecx+ecx*2]
577
		imul ebx,edx
578
		lea ebx,[ebx+ebx*2]
579
		mov esi,buf2d_data
580
		add esi,ebx
581
 
582
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
583
		mov ebx,buf2d_w
584
		imul ebx,edx
585
		lea ebx,[ebx+ebx*2]
586
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
587
		add edi,ebx
588
 
589
		cmp eax,0
590
		jg .move_down_24
591
			;двигаем изображение вверх
592
			cld
593
			rep movsb
594
			jmp .end_f
595
		.move_down_24:
596
			;двигаем изображение вниз
597
			add esi,ecx
598
			dec esi
599
			add edi,ecx
600
			dec edi
601
			std
602
			rep movsb
603
			jmp .end_f
604
	.end_move_24:
605
 
606
;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b
607
 
608
	cmp buf2d_bits,8
609
	jne .end_move_8
610
 
611
	mov eax,[hoffs]
612
	cmp eax,0
613
	je .end_move_8
614
		;двигаем изображение вверх
615
		mov ebx,buf2d_w
616
		mov edx,dword[img_t]
617
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
618
			cmp ecx,buf2d_h
619
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
620
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
621
		imul ebx,edx
622
		mov esi,buf2d_data
623
		add esi,ebx
624
 
625
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
626
		mov ebx,buf2d_w
627
		imul ebx,edx
628
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
629
		add edi,ebx
630
 
631
		cmp eax,0
632
		jg .move_down_8
633
			cld
634
			rep movsb
635
			jmp .end_f
636
		.move_down_8:
637
			;двигаем изображение вниз
638
			add esi,ecx
639
			dec esi
640
			add edi,ecx
641
			dec edi
642
			std
643
			rep movsb
644
			jmp .end_f
645
	.end_move_8:
646
 
647
	.end_f:
648
	popad
649
	ret
650
endp
651
 
652
 
653
align 4
654
proc buf_draw_buf, buf_struc:dword
655
	pushad
656
	mov edi,dword[buf_struc]
657
	cmp buf2d_bits,24
658
	jne .error
659
		mov eax,7
660
		mov ebx,buf2d_data
661
 
662
		mov ecx,buf2d_w
663
		ror ecx,16
664
		mov edx,buf2d_h
665
		mov cx,dx
666
 
667
		mov edx,buf2d_size_lt
668
		ror edx,16
669
		int 0x40
670
		jmp .end_draw_24
671
	.error:
672
		stdcall print_err,sz_buf2d_draw,txt_err_n24b
673
	.end_draw_24:
674
	popad
675
	ret
676
endp
677
 
678
align 4
679
proc buf_delete, buf_struc:dword
680
	push edi
681
	mov edi,dword[buf_struc]
682
	invoke mem.free,buf2d_data
683
	pop edi
684
	ret
685
endp
686
 
687
align 4
688
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
689
locals
690
	loc_1 dd ?
691
	loc_2 dd ?
692
	napravl db ?
693
endl
694
	pushad
695
		mov edx,dword[color]
696
 
697
		mov eax,dword[coord_x1]
698
		sub eax,dword[coord_x0]
699
		bt eax,31
700
		jae @f
701
			neg eax
702
			inc eax
703
		@@:
704
		mov ebx,dword[coord_y1]
705
		sub ebx,dword[coord_y0]
706
		bt ebx,31
707
		jae @f
708
			neg ebx
709
			inc ebx
710
		@@:
711
 
712
		mov [napravl],byte 0 ;bool steep=false
713
		cmp eax,ebx
714
		jle @f
715
			mov [napravl],byte 1 ;bool steep=true
716
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
717
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
718
		@@:
719
		mov eax,dword[coord_y0] ;x0
720
		cmp eax,dword[coord_y1] ;if(x0>x1)
721
		jle @f
722
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
723
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
724
		@@:
725
 
726
; int deltax esi
727
; int deltay edi
728
; int error  ebp-6
729
; int ystep  ebp-8
730
 
731
		mov eax,dword[coord_y0]
732
		mov esi,dword[coord_y1]
733
		sub esi,eax ;deltax = y1-y0
734
		mov ebx,esi
735
		shr ebx,1
736
		mov [loc_1],ebx ;error = deltax/2
737
 
738
		mov eax,dword[coord_x0]
739
		mov edi,dword[coord_x1]
740
		mov [loc_2],dword -1 ;ystep = -1
741
		cmp eax,edi ;if (x0
742
		jge @f
743
			mov [loc_2],dword 1 ;ystep = 1
744
		@@:
745
		sub edi,eax ;x1-x0
746
 
747
		bts edi,31
748
		jae @f
749
			neg edi
750
			inc edi
751
		@@:
752
		and edi,0x7fffffff ;deltay = abs(x1-x0)
753
 
754
		mov eax,edi
755
		mov edi,[buf_struc]
756
		cmp buf2d_bits,24
757
		jne .coord_end
758
 
759
		cmp [napravl],0
760
		jne .coord_yx
761
			mov ebx,dword[coord_x0]
762
			mov ecx,dword[coord_y0]
763
 
764
			@@: ;for (x=x0 ; x
765
				cmp ecx,dword[coord_y1]
766
				jg @f ;jge ???
767
				call draw_pixel
768
 
769
				sub dword[loc_1],eax ;error -= deltay
770
				cmp dword[loc_1],0 ;if(error<0)
771
				jge .if0
772
					add ebx,[loc_2] ;y += ystep
773
					add [loc_1],esi ;error += deltax
774
				.if0:
775
				inc ecx
776
				jmp @b
777
			@@:
778
			jmp .coord_end
779
		.coord_yx:
780
			mov ebx,dword[coord_y0]
781
			mov ecx,dword[coord_x0]
782
 
783
			@@: ;for (x=x0 ; x
784
				cmp ebx,dword[coord_y1]
785
				jg @f ;jge ???
786
				call draw_pixel
787
 
788
				sub dword[loc_1],eax ;error -= deltay
789
				cmp dword[loc_1],0 ;if(error<0)
790
				jge .if1
791
					add ecx,[loc_2] ;y += ystep
792
					add [loc_1],esi ;error += deltax
793
				.if1:
794
				inc ebx
795
				jmp @b
796
			@@:
797
	.coord_end:
798
	popad
799
	ret
800
endp
801
 
802
align 4
803
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
804
locals
805
	po_x dd ?
806
	po_y dd ?
807
endl
808
	pushad
809
	mov edi,dword[buf_struc]
810
	cmp buf2d_bits,24
811
	jne .error
812
		mov edx,dword[color]
813
 
814
		finit
815
		fild dword[coord_x]
816
		fild dword[coord_y]
817
		fild dword[r]
818
		fldz ;px=0
819
		fld st1 ;py=r
820
 
821
		fldpi
822
		fmul st0,st3
823
		fistp dword[po_x]
824
		mov esi,dword[po_x] ;esi=pi*r
825
		shl esi,1 ;esi=2*pi*r
826
 
827
		;st0 = py
828
		;st1 = px
829
		;st2 = r
830
		;st3 = y
831
		;st4 = x
832
 
833
		@@:
834
			;Point(px + x, y - py)
835
			fld st1 ;st0=px
836
			fadd st0,st5 ;st0=px+x
837
			fistp dword[po_x]
838
			mov ebx,dword[po_x]
839
			fld st3 ;st0=y
840
			fsub st0,st1 ;st0=y-py
841
			fistp dword[po_y]
842
			mov ecx,dword[po_y]
843
			call draw_pixel
844
			;px += py/r
845
			fld st0 ;st0=py
846
			fdiv st0,st3 ;st0=py/r
847
			faddp st2,st0 ;st3+=st0
848
			;py -= px/r
849
			fld st1 ;st0=px
850
			fdiv st0,st3 ;st0=px/r
851
			fsubp st1,st0 ;st2-=st0
852
 
853
			dec esi
854
			cmp esi,0
855
			jge @b
856
		jmp .exit_fun
857
	.error:
858
		stdcall print_err,sz_buf2d_circle,txt_err_n24b
859
	.exit_fun:
860
 
861
	popad
862
	ret
863
endp
864
 
865
align 4
866
proc buf_img_wdiv2, buf_struc:dword
867
	pushad
868
	mov edi,dword[buf_struc]
869
	cmp buf2d_bits,24
870
	jne .end_draw_24
871
		mov eax,buf2d_w
872
		mov ecx,buf2d_h
873
		imul ecx,eax
874
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
875
	.end_draw_24:
876
	popad
877
	ret
878
endp
879
 
880
;input:
881
;data_rgb - pointer to rgb data
882
;size - count img pixels (size img data / 3(rgb) )
883
align 4
884
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
885
  ;push eax ebx ecx edx
886
  mov eax,dword[data_rgb]
887
  mov ecx,dword[size] ;ecx = size
888
  lea ecx,[ecx+ecx*2]
889
  cld
890
  @@: ;затемнение цвета пикселей
891
    shr byte[eax],1
892
    inc eax
893
    loop @b
894
 
895
  mov eax,dword[data_rgb]
896
  mov ecx,dword[size] ;ecx = size
897
  shr ecx,1
898
  @@: ;сложение цветов пикселей
899
    mov bx,word[eax+3] ;копируем цвет соседнего пикселя
900
    add word[eax],bx
901
    mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
902
    add byte[eax+2],bl
903
    add eax,6 ;=2*3
904
    loop @b
905
 
906
  mov eax,dword[data_rgb]
907
  add eax,3
908
  mov ebx,eax
909
  add ebx,3
910
  mov ecx,dword[size] ;ecx = size
911
  shr ecx,1
912
  dec ecx ;лишний пиксель
913
  @@: ;поджатие пикселей
914
    mov edx,dword[ebx]
915
    mov word[eax],dx
916
    shr edx,16
917
    mov byte[eax+2],dl
918
 
919
    add eax,3
920
    add ebx,6
921
    loop @b
922
  ;pop edx ecx ebx eax
923
  ret
924
endp
925
 
926
align 4
927
proc buf_img_hdiv2, buf_struc:dword
928
	pushad
929
	mov edi,dword[buf_struc]
930
	cmp buf2d_bits,24
931
	jne .end_draw_24
932
		mov eax,buf2d_w
933
		mov ecx,buf2d_h
934
		imul ecx,eax
935
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
936
	.end_draw_24:
937
	popad
938
	ret
939
endp
940
 
941
;input:
942
;data_rgb - pointer to rgb data
943
;size - count img pixels (size img data / 3(rgb) )
944
;size_w - width img in pixels
945
align 4
946
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
947
  ;pushad
948
 
949
  mov eax,dword[data_rgb] ;eax =
950
  mov ecx,dword[size]	  ;ecx = size
951
  lea ecx,[ecx+ecx*2]
952
  cld
953
  @@: ;затемнение цвета пикселей
954
    shr byte[eax],1
955
    inc eax
956
    loop @b
957
 
958
  mov eax,dword[data_rgb] ;eax =
959
  mov edi,dword[size_w]
960
  lea esi,[edi+edi*2] ;esi = width*3(rgb)
961
  mov ebx,esi
962
  add ebx,eax
963
  mov ecx,dword[size]  ;ecx = size
964
  shr ecx,1
965
  xor edi,edi
966
  @@: ;сложение цветов пикселей
967
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
968
    add word[eax],dx
969
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
970
    add byte[eax+2],dl
971
 
972
    add eax,3
973
    add ebx,3
974
    inc edi
975
    cmp edi,dword[size_w]
976
    jl .old_line
977
      add eax,esi
978
      add ebx,esi
979
      xor edi,edi
980
    .old_line:
981
    loop @b
982
 
983
 
984
  mov eax,dword[data_rgb] ;eax =
985
  add eax,esi ;esi = width*3(rgb)
986
  mov ebx,esi
987
  add ebx,eax
988
  mov ecx,dword[size] ;ecx = size
989
  shr ecx,1
990
  sub ecx,dword[size_w] ;лишняя строка пикселей
991
  xor edi,edi
992
  @@: ;поджатие пикселей
993
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
994
    mov word[eax],dx
995
    shr edx,16
996
    mov byte[eax+2],dl
997
 
998
    add eax,3
999
    add ebx,3
1000
    inc edi
1001
    cmp edi,dword[size_w]
1002
    jl .old_line_2
1003
      add ebx,esi
1004
      xor edi,edi
1005
    .old_line_2:
1006
    loop @b
1007
 
1008
  ;popad
1009
  ret
1010
endp
1011
 
1012
;преобразование буфера из 24-битного в 8-битный
1013
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
1014
align 4
1015
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
1016
	pushad
1017
	mov edi,dword[buf_struc]
1018
	cmp buf2d_bits,24
1019
	jne .error
1020
		mov eax,buf2d_w
1021
		mov ecx,buf2d_h
1022
		imul ecx,eax
1023
		mov esi,ecx
1024
		;ebx - память из которой копируется
1025
		;edx - память куда копируется
1026
		mov edx,buf2d_data
1027
		mov ebx,edx
1028
		cmp [spectr],3
1029
		jge @f
1030
			add ebx,[spectr]
1031
		@@:
1032
			mov al,byte[ebx]
1033
			mov byte[edx],al
1034
			add ebx,3
1035
			inc edx
1036
			loop @b
1037
		mov buf2d_bits,8
1038
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
1039
		jmp .end_conv
1040
	.error:
1041
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
1042
	.end_conv:
1043
	popad
1044
	ret
1045
endp
1046
 
1047
;преобразование буфера из 24-битного в 32-битный
1048
align 4
1049
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
1050
	pushad
1051
	mov edi,dword[buf_struc]
1052
	cmp buf2d_bits,24
1053
	jne .error1
1054
		mov ecx,buf2d_w
1055
		mov ebx,buf2d_h
1056
		imul ebx,ecx
1057
		mov ecx,ebx ;ecx = size  8 b
1058
		shl ebx,2   ;ebx = size 32 b
1059
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
1060
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1061
		mov buf2d_bits,32
1062
		mov edx,ebx ;edx = size 32 b
1063
		sub ebx,ecx ;ebx = size 24 b
1064
		mov eax,ecx
1065
		;eax - размер  8 битных данных
1066
		;ebx - размер 24 битных данных
1067
		;edx - размер 32 битных данных
1068
		add ebx,buf2d_data
1069
		add edx,buf2d_data
1070
		mov edi,dword[buf_str8]
1071
		cmp buf2d_bits,8
1072
		jne .error2
1073
		add eax,buf2d_data
1074
		mov edi,edx
1075
		;eax - указатель на конец  8 битных данных
1076
		;ebx - указатель на конец 24 битных данных
1077
		;edi - указатель на конец 32 битных данных
1078
		@@:
1079
			sub edi,4 ;отнимаем в начале цикла,
1080
			sub ebx,3 ; потому, что указатели стоят
1081
			dec eax   ; за пределами буферов
1082
			mov edx,dword[ebx]
1083
			mov dword[edi],edx
1084
			mov dl,byte[eax]
1085
			mov byte[edi+3],dl
1086
			loop @b
1087
 
1088
		jmp .end_conv
1089
	.error1:
1090
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
1091
		jmp .end_conv
1092
	.error2:
1093
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
1094
	.end_conv:
1095
	popad
1096
	ret
1097
endp
1098
 
1099
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
1100
; указываются координаты вставки буфера buf_source относительно buf_destination
1101
; прозрачность при копировании не учитывается
1102
align 4
1103
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
1104
	locals
1105
		right_bytes dd ?
1106
	endl
1107
	pushad
1108
 
1109
	mov edi,[buf_source]
1110
	cmp buf2d_bits,24
1111
	je .sou24
1112
	cmp buf2d_bits,32
1113
	je .sou32
1114
		jmp .copy_end ;формат буфера не поодерживается
1115
 
1116
	.sou24: ;в источнике 32 битная картинка
1117
	mov eax,buf2d_w
1118
	mov edx,buf2d_h ;высота копируемой картинки
1119
	mov esi,buf2d_data ;данные копируемой картинки
1120
 
1121
	mov edi,[buf_destination]
1122
	cmp buf2d_bits,24
1123
	jne .copy_end ;формат буфера не поодерживается
1124
		mov ebx,buf2d_h ;ebx - высота основного буфера
1125
		mov ecx,[coord_y]
1126
		cmp ecx,ebx
1127
		jge .copy_end ;если координата 'y' больше высоты буфера
1128
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1129
		cmp ecx,ebx
1130
		jle @f
1131
			sub ecx,ebx
1132
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1133
		@@:
1134
		mov ebx,buf2d_w
1135
		mov ecx,ebx ;ecx используем для временных целей
1136
		imul ecx,[coord_y]
1137
		add ecx,[coord_x]
1138
		lea ecx,[ecx+ecx*2]
1139
		add ecx,buf2d_data
1140
		sub ebx,eax
1141
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1142
 
1143
	mov [right_bytes],0
1144
	mov ecx,[coord_x]
1145
	cmp ecx,ebx
1146
	jl @f
1147
		sub ecx,ebx
1148
		sub eax,ecx ;укорачиваем копируемую строку
1149
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1150
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
1151
		mov [right_bytes],ecx
1152
	@@:
1153
 
1154
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
1155
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
1156
 
1157
	cld
1158
	cmp [right_bytes],0
1159
	jg .copy_1
1160
	.copy_0: ;простое копирование
1161
		mov ecx,eax
1162
		rep movsb
1163
		add edi,ebx
1164
		dec edx
1165
		cmp edx,0
1166
		jg .copy_0
1167
	jmp .copy_end
1168
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
1169
		mov ecx,eax
1170
		rep movsb
1171
		add edi,ebx
1172
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
1173
		dec edx
1174
		cmp edx,0
1175
		jg .copy_1
1176
	jmp .copy_end
1177
 
1178
	.sou32: ;в источнике 32 битная картинка
1179
	mov eax,buf2d_w
1180
	mov edx,buf2d_h ;высота копируемой картинки
1181
	mov esi,buf2d_data ;данные копируемой картинки
1182
 
1183
	mov edi,[buf_destination]
1184
	cmp buf2d_bits,24
1185
	jne .copy_end ;формат буфера не поодерживается
1186
		mov ebx,buf2d_h ;ebx - высота основного буфера
1187
		mov ecx,[coord_y]
1188
		cmp ecx,ebx
1189
		jge .copy_end ;если координата 'y' больше высоты буфера
1190
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1191
		cmp ecx,ebx
1192
		jle @f
1193
			sub ecx,ebx
1194
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1195
		@@:
1196
		mov ebx,buf2d_w
1197
		mov ecx,ebx ;ecx используем для временных целей
1198
		imul ecx,[coord_y]
1199
		add ecx,[coord_x]
1200
		lea ecx,[ecx+ecx*2]
1201
		add ecx,buf2d_data
1202
		sub ebx,eax
1203
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1204
 
1205
	mov [right_bytes],0
1206
	mov ecx,[coord_x]
1207
	cmp ecx,ebx
1208
	jl @f
1209
		sub ecx,ebx
1210
		sub eax,ecx ;укорачиваем копируемую строку
1211
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1212
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
1213
		mov [right_bytes],ecx
1214
	@@:
1215
 
1216
	;eax - колличество пикселей в 1-й строке копируемой картинки
1217
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
1218
 
1219
	cld
1220
	cmp [right_bytes],0
1221
	jg .copy_3
1222
	.copy_2: ;простое копирование
1223
		mov ecx,eax
1224
		@@:
1225
			movsw
1226
			movsb
1227
			inc esi
1228
			loop @b
1229
		add edi,ebx
1230
		dec edx
1231
		cmp edx,0
1232
		jg .copy_2
1233
	jmp .copy_end
1234
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
1235
		mov ecx,eax
1236
		@@:
1237
			movsw
1238
			movsb
1239
			inc esi
1240
			loop @b
1241
		add edi,ebx
1242
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
1243
		dec edx
1244
		cmp edx,0
1245
		jg .copy_3
1246
 
1247
	.copy_end:
1248
	popad
1249
	ret
1250
endp
1251
 
1252
;input:
1253
; esi = pointer to color1 + transparent
1254
; edi = pointer to background color2
1255
;output:
1256
; [edi] = combine color
1257
align 4
1258
combine_colors:
1259
	push ax bx cx dx
1260
	mov bx,0x00ff ;---get transparent---
1261
	mov cl,byte[esi+3] ;pro
1262
	xor ch,ch
1263
	sub bx,cx ;256-pro
1264
	;---red---
1265
	xor ah,ah
1266
	mov al,byte[esi+2]
1267
	imul ax,bx
1268
	xor dh,dh
1269
	mov dl,byte[edi+2]
1270
	imul dx,cx
1271
	add ax,dx
1272
	mov byte[edi+2],ah
1273
	;---green---
1274
	xor ah,ah
1275
	mov al,byte[esi+1]
1276
	imul ax,bx
1277
	xor dh,dh
1278
	mov dl,byte[edi+1]
1279
	imul dx,cx
1280
	add ax,dx
1281
	mov byte[edi+1],ah
1282
	;---blye---
1283
	xor ah,ah
1284
	mov al,byte[esi]
1285
	imul ax,bx
1286
	xor dh,dh
1287
	mov dl,byte[edi]
1288
	imul dx,cx
1289
	add ax,dx
1290
	mov byte[edi],ah
1291
 
1292
	pop dx cx bx ax
1293
	ret
1294
 
1295
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
1296
; указываются координаты вставки буфера buf_source относительно buf_destination
1297
; при копировании учитывается прозрачность
1298
align 4
1299
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
1300
	locals
1301
		right_bytes dd ?
1302
	endl
1303
	pushad
1304
 
1305
	mov edi,[buf_source]
1306
	cmp buf2d_bits,32
1307
	jne .copy_end ;формат буфера не поодерживается
1308
	mov eax,buf2d_w
1309
	mov edx,buf2d_h ;высота копируемой картинки
1310
	mov esi,buf2d_data ;данные копируемой картинки
1311
 
1312
	mov edi,[buf_destination]
1313
	cmp buf2d_bits,24
1314
	jne .copy_end ;формат буфера не поодерживается
1315
		mov ebx,buf2d_h ;ebx - высота основного буфера
1316
		mov ecx,[coord_y]
1317
		cmp ecx,ebx
1318
		jge .copy_end ;если координата 'y' больше высоты буфера
1319
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1320
		cmp ecx,ebx
1321
		jle @f
1322
			sub ecx,ebx
1323
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1324
		@@:
1325
		mov ebx,buf2d_w
1326
		mov ecx,ebx ;ecx используем для временных целей
1327
		imul ecx,[coord_y]
1328
		add ecx,[coord_x]
1329
		lea ecx,[ecx+ecx*2]
1330
		add ecx,buf2d_data
1331
		sub ebx,eax
1332
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1333
 
1334
	mov [right_bytes],0
1335
	mov ecx,[coord_x]
1336
	cmp ecx,ebx
1337
	jl @f
1338
		sub ecx,ebx
1339
		sub eax,ecx ;укорачиваем копируемую строку
1340
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1341
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
1342
		mov [right_bytes],ecx
1343
	@@:
1344
 
1345
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
1346
 
1347
	cld
1348
	cmp [right_bytes],0
1349
	jg .copy_1
1350
	.copy_0: ;простое копирование
1351
		mov ecx,eax
1352
		@@:
1353
			call combine_colors
1354
			add edi,3
1355
			add esi,4
1356
			loop @b
1357
		add edi,ebx
1358
		dec edx
1359
		cmp edx,0
1360
		jg .copy_0
1361
	jmp .copy_end
1362
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
1363
		mov ecx,eax
1364
		@@:
1365
			call combine_colors
1366
			add edi,3
1367
			add esi,4
1368
			loop @b
1369
		add edi,ebx
1370
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
1371
		dec edx
1372
		cmp edx,0
1373
		jg .copy_1
1374
 
1375
	.copy_end:
1376
	popad
1377
	ret
1378
endp
1379
 
1380
;input:
1381
; ebx - color1
1382
; esi = pointer to transparent
1383
; edi = pointer to background color2
1384
;output:
1385
; [edi] = combine color
1386
align 4
1387
combine_colors_2:
1388
	push ax ebx cx dx si
1389
	mov cl,byte[esi] ;pro
1390
	xor ch,ch
1391
	mov si,0x00ff ;---get transparent---
1392
	sub si,cx ;256-pro
1393
 
1394
	;---blye---
1395
		mov al,bl
1396
		xor ah,ah
1397
		shr ebx,8
1398
		imul ax,si
1399
		xor dh,dh
1400
		mov dl,byte[edi+2]
1401
		imul dx,cx
1402
		add ax,dx
1403
		mov byte[edi+2],ah
1404
		;---green---
1405
		mov al,bl
1406
		xor ah,ah
1407
		shr ebx,8
1408
		imul ax,si
1409
		xor dh,dh
1410
		mov dl,byte[edi+1]
1411
		imul dx,cx
1412
		add ax,dx
1413
		mov byte[edi+1],ah
1414
		;---red---
1415
		mov al,bl
1416
		xor ah,ah
1417
		imul ax,si
1418
		xor dh,dh
1419
		mov dl,byte[edi]
1420
		imul dx,cx
1421
		add ax,dx
1422
		mov byte[edi],ah
1423
 
1424
	pop si dx cx ebx ax
1425
	ret
1426
 
1427
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
1428
; указываются координаты вставки буфера buf_source относительно buf_destination
1429
align 4
1430
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
1431
	locals
1432
		right_bytes dd ?
1433
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
1434
	endl
1435
	pushad
1436
 
1437
	mov edi,[buf_source]
1438
	cmp buf2d_bits,8
1439
	jne .error1 ;формат буфера не поодерживается
1440
	mov eax,buf2d_w
1441
	mov edx,buf2d_h ;высота копируемой картинки
1442
	mov esi,buf2d_data ;данные копируемой картинки
1443
 
1444
	mov edi,[buf_destination]
1445
	cmp buf2d_bits,24
1446
	jne .error2 ;формат буфера не поодерживается
1447
		mov ebx,buf2d_h ;ebx - высота основного буфера
1448
		mov ecx,[coord_y]
1449
		cmp ecx,ebx
1450
		jge .copy_end ;если координата 'y' больше высоты буфера
1451
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1452
		cmp ecx,ebx
1453
		jle @f
1454
			sub ecx,ebx
1455
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1456
		@@:
1457
		mov ebx,buf2d_w
1458
		mov ecx,ebx ;ecx используем для временных целей
1459
		imul ecx,[coord_y]
1460
		add ecx,[coord_x]
1461
		lea ecx,[ecx+ecx*2]
1462
		add ecx,buf2d_data
1463
		sub ebx,eax
1464
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1465
 
1466
	mov [right_bytes],0
1467
	mov ecx,[coord_x]
1468
	cmp ecx,ebx
1469
	jl @f
1470
		sub ecx,ebx
1471
		sub eax,ecx ;укорачиваем копируемую строку
1472
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1473
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
1474
		mov [right_bytes],ecx
1475
	@@:
1476
 
1477
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
1478
	mov [dest_w_bytes],ebx
1479
	mov ebx,[color]
1480
 
1481
	cld
1482
	cmp [right_bytes],0
1483
	jg .copy_1
1484
	.copy_0: ;простое копирование
1485
		mov ecx,eax
1486
		@@:
1487
			call combine_colors_2
1488
			add edi,3
1489
			inc esi
1490
			loop @b
1491
		add edi,[dest_w_bytes]
1492
		dec edx
1493
		cmp edx,0
1494
		jg .copy_0
1495
	jmp .copy_end
1496
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
1497
		mov ecx,eax
1498
		@@:
1499
			call combine_colors_2
1500
			add edi,3
1501
			inc esi
1502
			loop @b
1503
		add edi,[dest_w_bytes]
1504
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
1505
		dec edx
1506
		cmp edx,0
1507
		jg .copy_1
1508
 
1509
	jmp .copy_end
1510
	.error1:
1511
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
1512
		jmp .copy_end
1513
	.error2:
1514
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
1515
	.copy_end:
1516
	popad
1517
	ret
1518
endp
1519
 
1520
;преобразование 8-битного буфера размером 16*16 в размер 1*256 символов
1521
align 4
1522
proc buf_convert_text_matrix, buf_struc:dword
1523
	locals
1524
		tmp_mem dd ?
1525
		c1 dw ?
1526
		c2 dd ?
1527
		c3 dw ?
1528
	endl
1529
	pushad
1530
	mov edi,dword[buf_struc]
1531
	cmp buf2d_bits,8
1532
	jne .error
1533
		mov ecx,buf2d_h
1534
		mov ebx,ecx
1535
		shr ebx,4 ;предполагаем что в буфере 16 строк с символами, потому делим на 2^4
1536
		mov edx,buf2d_w
1537
		imul ecx,edx ;ecx = size  8 b
1538
		invoke mem.alloc,ecx ;выделяем временную память
1539
		mov [tmp_mem],eax ;eax - new memory
1540
 
1541
		shr edx,4 ;предполагаем что в буфере 16 колонок с символами, потому делим на 2^4
1542
		mov eax,ebx
1543
		imul ebx,edx ;вычисляем кооличество пикселей на 1 символ
1544
		;eax = bhe - высота буквы
1545
		;ebx = bwi*bhe - колличество пикселей в 1-й букве
1546
		;edx = bwi - ширина буквы
1547
		;ecx,esi,edi - используются в цикле .c_0
1548
		shr buf2d_w,4
1549
		shl buf2d_h,4 ;преобразовываем размеры буфера
1550
 
1551
		cld
1552
		mov esi,buf2d_data
1553
		mov edi,[tmp_mem]
1554
		mov word[c3],16
1555
		.c_3:
1556
			mov dword[c2],eax
1557
			.c_2:
1558
				mov word[c1],16
1559
				.c_1:
1560
					mov ecx,edx ;.c_0:
1561
					rep movsb
1562
					add edi,ebx
1563
					sub edi,edx ;edi+=(bwi*bhe-bwi)
1564
					dec word[c1]
1565
					cmp word[c1],0
1566
					jg .c_1
1567
				add edi,edx
1568
				shl ebx,4
1569
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
1570
				shr ebx,4
1571
				dec dword[c2]
1572
				cmp dword[c2],0
1573
				jg .c_2
1574
			sub edi,ebx
1575
			shl ebx,4
1576
			add edi,ebx ;edi+=(15*bwi*bhe)
1577
			shr ebx,4
1578
			dec word[c3]
1579
			cmp word[c3],0
1580
			jg .c_3
1581
 
1582
		mov edi,dword[buf_struc] ;копирование новой матрицы в основной буфер
1583
		mov edi,buf2d_data
1584
		mov esi,[tmp_mem]
1585
		mov ecx,ebx
1586
		shl ecx,8
1587
		rep movsb
1588
		invoke mem.free,[tmp_mem] ;чистим временную память
1589
		jmp .end_conv
1590
	.error:
1591
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
1592
	.end_conv:
1593
	popad
1594
	ret
1595
endp
1596
 
1597
align 4
1598
buf_s_matr buf_2d_header ? ;локальная матрица символа
1599
 
1600
align 4
1601
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
1602
	locals
1603
		buf_t_matr_offs dd ?
1604
	endl
1605
	pushad
1606
	mov edi,dword[buf_struc]
1607
	cmp buf2d_bits,24
1608
	jne .error2
1609
	mov edi,dword[buf_t_matr]
1610
	cmp buf2d_bits,8
1611
	jne .error1
1612
		mov edx,buf2d_data
1613
		mov [buf_t_matr_offs],edx
1614
		mov ecx,BUF_STRUCT_SIZE ;копируем структуру текстовой матрицы
1615
		mov esi,edi
1616
		lea edi,[buf_s_matr]
1617
		cld
1618
		rep movsb
1619
		lea edi,[buf_s_matr]
1620
		shr buf2d_h,8 ;делим высоту символьного буфера на 256, для нахождения высоты 1-го символа
1621
		mov ebx,buf2d_h ;берем высоту символа
1622
		mov ecx,buf2d_w ;берем ширину символа
1623
 
1624
		mov eax,[coord_x]
1625
		mov esi,[text]
1626
		cmp byte[esi],0
1627
		je .end_draw ;если пустая строка
1628
		@@:
1629
			xor edx,edx
1630
			mov dl,byte[esi] ;берем код символа
1631
			imul edx,ebx ;умножаем его на высоту символа
1632
			imul edx,ecx ;умножаем на ширину символа
1633
			add edx,[buf_t_matr_offs] ;прибавляем смещение 0-го символа, т. е. получается смещение выводимого символа
1634
			mov buf2d_data,edx ;в локальный буфер символа, ставим указатель на нужный символ из буфера buf_t_matr
1635
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
1636
			add eax,ecx
1637
			.new_s:
1638
				inc esi
1639
				cmp byte[esi],13
1640
				jne .no_13
1641
					mov eax,[coord_x]
1642
					add [coord_y],ebx
1643
					jmp .new_s
1644
				.no_13:
1645
			cmp byte[esi],0
1646
			jne @b
1647
		jmp .end_draw
1648
	.error1:
1649
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
1650
		jmp .end_draw
1651
	.error2:
1652
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
1653
	.end_draw:
1654
	popad
1655
	ret
1656
endp
1657
 
1658
align 4
1659
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
1660
	pushad
1661
	mov eax,63
1662
	mov ebx,1
1663
 
1664
	mov esi,[fun]
1665
	@@:
1666
		mov cl,byte[esi]
1667
		int 0x40
1668
		inc esi
1669
		cmp byte[esi],0
1670
		jne @b
1671
	mov cl,':'
1672
	int 0x40
1673
	mov cl,' '
1674
	int 0x40
1675
	mov esi,[mes]
1676
	@@:
1677
		mov cl,byte[esi]
1678
		int 0x40
1679
		inc esi
1680
		cmp byte[esi],0
1681
		jne @b
1682
	popad
1683
	ret
1684
endp
1685
 
1686
;input:
1687
; ebp+8  = p0
1688
; ebp+12 = p1
1689
align 4
1690
line_len4i:
1691
	push ebp
1692
	mov ebp,esp
1693
		finit
1694
		fild word [ebp+8]
1695
		fisub word [ebp+12]
1696
		fmul st0,st0 ;st0=x^2
1697
		fild word [ebp+10]
1698
		fisub word [ebp+14]
1699
		fmul st0,st0 ;st0=y^2
1700
		fadd st0,st1
1701
		fsqrt
1702
		fstp dword [ebp+12]
1703
	pop ebp
1704
	ret 4 ;8
1705
 
1706
align 4
1707
proc buf_cruve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
1708
	locals
1709
		delt_t dd ?
1710
		opr_param dd ?
1711
		v_poi_0 dd ?
1712
	endl
1713
	pushad
1714
 
1715
;float t, xt,yt;
1716
;for(t=.0;t<1.;t+=.005){
1717
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
1718
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
1719
;  dc.SetPixel(xt,yt,255L);
1720
;}
1721
 
1722
	mov edx,[color] ;set cruve color
1723
	mov edi,[buffer]
1724
	xor ebx,ebx
1725
	xor ecx,ecx
1726
 
1727
	finit
1728
 
1729
	; calculate delta t
1730
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
1731
	fadd dword[esp]
1732
	add esp,4 ;pop ...
1733
 
1734
	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
1735
	fadd dword[esp]
1736
	add esp,4 ;pop ...
1737
 
1738
	fadd st0,st0 ; len*=2
1739
	ftst
1740
	fstsw ax
1741
 
1742
	fld1
1743
	sahf
1744
	jle @f ;избегаем деления на 0
1745
		fdiv st0,st1
1746
	@@:
1747
	fstp dword[delt_t]
1748
 
1749
	finit
1750
 
1751
	;fild word[coord_p2+2] ;y2
1752
	fild word[coord_p1+2] ;y1
1753
	fild word[coord_p0+2] ;y0
1754
	fild word[coord_p2] ;x2
1755
	fild word[coord_p1] ;x1
1756
	fild word[coord_p0] ;x0
1757
	fld dword[delt_t]
1758
	fldz ;t=.0
1759
 
1760
	@@:
1761
		fld1
1762
		fsub st0,st1 ;1.-t
1763
		fmul st0,st0 ;pow(1.-t,2)
1764
		fmul st0,st3 ;...*x0
1765
		fstp dword[opr_param]
1766
 
1767
		fld1
1768
		fsub st0,st1 ;1.-t
1769
		fmul st0,st1 ;(1.-t)*t
1770
		fadd st0,st0
1771
		fmul st0,st4 ;...*x1
1772
		mov esi,dword[opr_param]
1773
		fstp dword[opr_param]
1774
 
1775
		fldz
1776
		fadd st0,st1 ;0+t
1777
		fmul st0,st0 ;t*t
1778
		fmul st0,st5 ;...*x2
1779
 
1780
		fadd dword[opr_param]
1781
		mov dword[opr_param],esi
1782
		fadd dword[opr_param]
1783
		fistp word[v_poi_0] ;x
1784
 
1785
		fld1
1786
		fsub st0,st1 ;1.-t
1787
		fmul st0,st0 ;pow(1.-t,2)
1788
		fmul st0,st6 ;...*y0
1789
		fstp dword[opr_param]
1790
 
1791
		fld1
1792
		fsub st0,st1 ;1.-t
1793
		fmul st0,st1 ;(1.-t)*t
1794
		fadd st0,st0
1795
		fmul st0,st7 ;...*y1
1796
		mov esi,dword[opr_param]
1797
		fstp dword[opr_param]
1798
 
1799
		fldz
1800
		fadd st0,st1 ;0+t
1801
		fmul st0,st0 ;t*t
1802
		fimul word[coord_p2+2] ;...*y2
1803
 
1804
		fadd dword[opr_param]
1805
		mov dword[opr_param],esi
1806
		fadd dword[opr_param]
1807
		fistp word[v_poi_0+2] ;y
1808
 
1809
		mov eax,1
1810
		mov bx,word[v_poi_0+2]
1811
		mov cx,word[v_poi_0]
1812
		call draw_pixel
1813
 
1814
		fadd st0,st1 ;t+dt
1815
 
1816
		fld1
1817
		fcomp
1818
		fstsw ax
1819
		sahf
1820
	jae @b
1821
 
1822
	popad
1823
	ret
1824
endp
1825
 
1826
txt_err_n8b db 'need buffer 8 bit',13,10,0
1827
txt_err_n24b db 'need buffer 24 bit',13,10,0
1828
 
1829
align 16
1830
EXPORTS:
1831
	dd sz_lib_init, lib_init
1832
	dd sz_buf2d_create, buf_create
1833
	dd sz_buf2d_create_f_img, buf_create_f_img
1834
	dd sz_buf2d_clear, buf_clear
1835
	dd sz_buf2d_draw, buf_draw_buf
1836
	dd sz_buf2d_delete, buf_delete
1837
	dd sz_buf2d_line, buf_line_brs
1838
	dd sz_buf2d_circle, buf_circle
1839
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
1840
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
1841
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
1842
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
1843
	dd sz_buf2d_bit_blt, buf_bit_blt
1844
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
1845
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1846
	dd sz_buf2d_cruve_bezier, buf_cruve_bezier
1847
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
1848
	dd sz_buf2d_draw_text, buf_draw_text
1849
	dd sz_buf2d_crop_color, buf_crop_color
1850
	dd sz_buf2d_offset_h, buf_offset_h
1851
	dd 0,0
1852
	sz_lib_init db 'lib_init',0
1853
	sz_buf2d_create db 'buf2d_create',0
1854
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
1855
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
1856
	sz_buf2d_draw db 'buf2d_draw',0
1857
	sz_buf2d_delete db 'buf2d_delete',0
1858
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
1859
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
1860
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
1861
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
1862
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
1863
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
1864
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
1865
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
1866
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1867
	sz_buf2d_cruve_bezier db 'buf2d_cruve_bezier',0
1868
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
1869
	sz_buf2d_draw_text db 'buf2d_draw_text',0
1870
	sz_buf2d_crop_color db 'buf2d_crop_color',0
1871
	sz_buf2d_offset_h db 'buf2d_offset_h',0