format MS COFF
public EXPORTS
section '.flat' code readable align 16

include '../../../../macros.inc'
include '../../../../proc32.inc'

;-----------------------------------------------------------------------------
mem.alloc   dd ? ;äã­ªæ¨ï ¤«ï ¢ë¤¥«¥­¨ï ¯ ¬ïâ¨
mem.free    dd ? ;äã­ªæ¨ï ¤«ï ®á¢®¡®¦¤¥­¨ï ¯ ¬ïâ¨
mem.realloc dd ? ;äã­ªæ¨ï ¤«ï ¯¥à¥à á¯à¥¤¥«¥­¨ï ¯ ¬ïâ¨
dll.load    dd ?

BUF_STRUCT_SIZE equ 21
buf2d_data equ dword[edi] ;¤ ­­ë¥ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
buf2d_w equ dword[edi+8] ;è¨à¨­  ¡ãä¥à 
buf2d_h equ dword[edi+12] ;¢ëá®â  ¡ãä¥à 
buf2d_l equ word[edi+4]
buf2d_t equ word[edi+6] ;®âáâ㯠ᢥàåã
buf2d_size_lt equ dword[edi+4] ;®âáâ㯠᫥¢  ¨ á¯à ¢  ¤«ï ¡ãä¥à 
buf2d_color equ dword[edi+16] ;梥â ä®­  ¡ãä¥à 
buf2d_bits equ byte[edi+20] ;ª®«¨ç¥á⢮ ¡¨â ¢ 1-© â®çª¥ ¨§®¡à ¦¥­¨ï

struct buf_2d_header
	img_data dd ?
	left dw ? ;+4 left
	top dw ? ;+6 top
	size_x dd ? ;+8 w
	size_y dd ? ;+12 h
	color dd ? ;+16 color
	bit_pp db ? ;+21 bit in pixel
ends

macro swap v1, v2 {
  push v1
  push v2
  pop v1
  pop v2
}

;ä« £¨, ¤«ï ä㭪樨 ®¡à¥§ ­¨ï ¡ãä¥à 
BUF2D_OPT_CROP_TOP equ 1 ;®¡à¥§ª  ᢥàåã
BUF2D_OPT_CROP_LEFT equ 2 ;®¡à¥§ª  á«¥¢ 
BUF2D_OPT_CROP_BOTTOM equ 4 ;®¡à¥§ª  á­¨§ã
BUF2D_OPT_CROP_RIGHT equ 8 ;®¡à¥§ª  á¯à ¢ 
BUF2D_BIT_OPT_CROP_TOP equ 0
BUF2D_BIT_OPT_CROP_LEFT equ 1
BUF2D_BIT_OPT_CROP_BOTTOM equ 2
BUF2D_BIT_OPT_CROP_RIGHT equ 3

vox_offs_tree_table equ 4
vox_offs_data equ 12

;input:
; eax = 㪠§ â¥«ì ­  äã­ªæ¨î ¢ë¤¥«¥­¨ï ¯ ¬ïâ¨
; ebx = ... ®á¢®¡®¦¤¥­¨ï ¯ ¬ïâ¨
; ecx = ... ¯¥à¥à á¯à¥¤¥«¥­¨ï ¯ ¬ïâ¨
; edx = ... § £à㧪¨ ¡¨¡«¨®â¥ª¨ (¯®ª  ­¥ ¨á¯®«ì§ã¥âáï)
align 16
lib_init:
	mov dword[mem.alloc], eax
	mov dword[mem.free], ebx
	mov dword[mem.realloc], ecx
	mov dword[dll.load], edx
	ret

;input:
; ebx = coord x
; ecx = coord y
; edx = pixel color
; edi = pointer to buffer struct
align 4
draw_pixel:
	;cmp buf2d_bits,24
	;jne @f
	bt ebx,31
	jc @f
	bt ecx,31
	jc @f
	cmp ebx,buf2d_w
	jge @f
	cmp ecx,buf2d_h
	jge @f
	push esi
		mov esi,buf2d_w ;size x
		imul esi,ecx ;size_x*y
		add esi,ebx	 ;size_x*y+x
		cmp buf2d_bits,8
		je .beg8
		cmp buf2d_bits,32
		je .beg32
			lea esi,[esi+esi*2] ;(size_x*y+x)*3
			add esi,buf2d_data  ;ptr+(size_x*y+x)*3
			mov word[esi],dx ;copy pixel color
			ror edx,16
			mov byte[esi+2],dl
			ror edx,16
			jmp .end_draw
		.beg8: ;à¨á®¢ ­¨¥ â®çª¨ ¢ 8 ¡¨â­®¬ ¡ãä¥à¥
			add esi,buf2d_data  ;ptr+(size_x*y+x)
			mov byte[esi],dl
			jmp .end_draw
		.beg32: ;à¨á®¢ ­¨¥ â®çª¨ ¢ 32 ¡¨â­®¬ ¡ãä¥à¥
			shl esi,2
			add esi,buf2d_data  ;ptr+(size_x*y+x)
			mov dword[esi],edx
		.end_draw:
	pop esi
	@@:
	ret

;input:
; ebx = coord x
; ecx = coord y
; edi = pointer to buffer struct
;output:
; eax = 梥â â®çª¨
; ¢ á«ãç ¥ ®è¨¡ª¨ eax = 0xffffffff
align 4
get_pixel_8:
	mov eax,0xffffffff

	bt ebx,31
	jc @f
	bt ecx,31
	jc @f
	cmp ebx,buf2d_w
	jge @f
	cmp ecx,buf2d_h
	jge @f
	push esi
		mov esi,buf2d_w ;size x
		imul esi,ecx ;size_x*y
		add esi,ebx	 ;size_x*y+x
		add esi,buf2d_data  ;ptr+(size_x*y+x)

		movzx eax,byte[esi] ;copy pixel color
	pop esi
	@@:
	ret

;input:
; ebx = coord x
; ecx = coord y
; edi = pointer to buffer struct
;output:
; eax = 梥â â®çª¨
; ¢ á«ãç ¥ ®è¨¡ª¨ eax = 0xffffffff
align 4
get_pixel_24:
	mov eax,0xffffffff

	bt ebx,31
	jc @f
	bt ecx,31
	jc @f
	cmp ebx,buf2d_w
	jge @f
	cmp ecx,buf2d_h
	jge @f
	push esi
		mov esi,buf2d_w ;size x
		imul esi,ecx ;size_x*y
		add esi,ebx	 ;size_x*y+x
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3

		xor eax,eax
		mov ax,word[esi] ;copy pixel color
		ror eax,16
		mov al,byte[esi+2]
		ror eax,16
	pop esi
	@@:
	ret

;input:
; ebx = coord x
; ecx = coord y
; edi = pointer to buffer struct
;output:
; eax = 梥â â®çª¨
; ¢ á«ãç ¥ ®è¨¡ª¨ eax = 0xffffffff
align 4
get_pixel_32:
	mov eax,0xffffffff

	bt ebx,31
	jc @f
	bt ecx,31
	jc @f
	cmp ebx,buf2d_w
	jge @f
	cmp ecx,buf2d_h
	jge @f
	push esi
		mov esi,buf2d_w ;size x
		imul esi,ecx ;size_x*y
		add esi,ebx	 ;size_x*y+x
		shl esi,2
		add esi,buf2d_data  ;ptr+(size_x*y+x)*4

		mov eax,dword[esi] ;copy pixel color
	pop esi
	@@:
	ret

;input:
; ebx = coord x
; ecx = coord y
; edx = pixel color + transparent
; edi = pointer to buffer struct
; t_prop, m_prop - ª®íä¨æ¨¥­âë ­¥®¡å®¤¨¬ë¥ ¤«ï ¢ëç¨á«¥­¨ï á⥯¥­¨ ¯à®§à ç­®áâ¨
align 4
transp_32 dd 0 ;梥â à¨á㥬®© â®çª¨ + ¯à®§à ç­®áâì
align 4
proc draw_pixel_transp, t_prop:dword, m_prop:dword
	;cmp buf2d_bits,24
	;jne @f
	bt ebx,31
	jc @f
	bt ecx,31
	jc @f
	cmp ebx,buf2d_w
	jge @f
	cmp ecx,buf2d_h
	jge @f
	push eax ebx edx edi esi
		mov esi,buf2d_w ;size x
		imul esi,ecx ;size_x*y
		add esi,ebx	 ;size_x*y+x
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3

		mov edi,esi ;㪠§ â¥«ì ­  梥â ä®­ 
		mov dword[transp_32],edx ;梥â à¨á㥬®© â®çª¨

		xor edx,edx
		mov eax,[t_prop]
		shl eax,8 ;*=256
		mov ebx,[m_prop]
		div ebx ;¢ëç¨á«ï¥¬ ª®íä. ¯à®§à ç­®á⨠(¤®«¦¥­ ¡ëâì ®â 0 ¤® 255)
		bt ax,8
		jnc .over_255
			;¥á«¨ ª®¥ä. ¯à®§à ç­®á⨠>=256 ⮠㬥­ìè ¥¬ ¥£® ¤® 255
			mov al,0xff
		.over_255:

		mov byte[transp_32+3],al ;¯à®§à ç­®áâì à¨á㥬®© â®çª¨
		mov esi,dword transp_32 ;㪠§ â¥«ì ­  梥â à¨á㥬®© â®çª¨

		call combine_colors_0
	pop esi edi edx ebx eax
	@@:
	ret
endp

;ᮧ¤ ­¨¥ ¡ãä¥à 
align 4
proc buf_create, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	mov ecx,buf2d_w
	mov ebx,buf2d_h
	imul ecx,ebx
	cmp buf2d_bits,24
	jne @f
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
		;;;inc ecx ;§ ¯ á­®© ¡ ©â ¢ ª®­æ¥ ¡ãä¥à , çâ®-¡ë ­¥ £«î稫¨ ­¥ª®â®àë¥ ä㭪樨 ­  ¨§®¡à ¦¥­¨ïå ªà â­ëå 4Š
	@@:
	cmp buf2d_bits,32
	jne @f
		shl ecx,2 ; 32 bit = 4
	@@:
	invoke mem.alloc,ecx
	mov buf2d_data,eax

	stdcall buf_clear,edi,buf2d_color ;®ç¨á⪠ ¡ãä¥à  ä®­®¢ë¬ 梥⮬
	popad
	ret
endp

;ᮧ¤ ­¨¥ ¡ãä¥à  ­  ®á­®¢¥ ¨§®¡à ¦¥­¨ï rgb
align 4
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
	pushad
	mov edi,dword[buf_struc]
	mov ecx,buf2d_w
	mov ebx,buf2d_h
	imul ecx,ebx
	cmp buf2d_bits,24
	jne @f
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
		;;;inc ecx ;§ ¯ á­®© ¡ ©â ¢ ª®­æ¥ ¡ãä¥à , çâ®-¡ë ­¥ £«î稫¨ ­¥ª®â®àë¥ ä㭪樨 ­  ¨§®¡à ¦¥­¨ïå ªà â­ëå 4Š
	@@:
	cmp buf2d_bits,32
	jne @f
		shl ecx,2 ; 32 bit = 4
	@@:
	invoke mem.alloc,ecx
	mov buf2d_data,eax

	cmp buf2d_bits,24
	jne @f
		cld
		mov esi,[rgb_data]
		mov edi,eax ;eax=buf2d_data
		rep movsb ;ª®¯¨à㥬 ¡¨âë ¨§®¡à ¦¥­¨ï ¢ ¡ãä¥à
		jmp .end_create
	@@:
		stdcall buf_clear,edi,buf2d_color ;®ç¨á⪠ ¡ãä¥à  ä®­®¢ë¬ 梥⮬
	.end_create:
	popad
	ret
endp

align 4
proc buf_clear, buf_struc:dword, color:dword ;®ç¨á⪠ ¡ãä¥à  § ¤ ­ë¬ 梥⮬
	pushad
	mov edi,dword[buf_struc]

	mov ecx,buf2d_w
	mov ebx,buf2d_h
	imul ecx,ebx

	cld

	cmp buf2d_bits,8
	jne .end_clear_8
		mov edi,buf2d_data
		mov al,byte[color]
		rep stosb
		jmp .end_clear_32
	.end_clear_8:

	cmp buf2d_bits,24
	jne .end_clear_24
		mov edi,buf2d_data
		mov eax,dword[color]
		mov ebx,eax
		shr ebx,16
		@@:
			stosw
			mov byte[edi],bl
			inc edi
			loop @b
		jmp .end_clear_32
	.end_clear_24:

	cmp buf2d_bits,32
	jne .end_clear_32
		mov edi,buf2d_data
		mov eax,dword[color]
		rep stosd
		;jmp .end_clear_32
	.end_clear_32:
	popad
	ret
endp

;äã­ªæ¨ï ¤«ï ®¡à¥§ ­¨ï ¡ãä¥à®¢ 8 ¨ 24 ¡¨â­ëå, ¯® § ¤ ­®¬ã 梥âã.
;¯ à ¬¥âà opt § ¤ ¥âáï ª®¬¡¨­ æ¨¥© ª®­áâ ­â:
; BUF2D_OPT_CROP_TOP - ®¡à¥§ª  ᢥàåã
; BUF2D_OPT_CROP_LEFT - ®¡à¥§ª  á«¥¢ 
; BUF2D_OPT_CROP_BOTTOM - ®¡à¥§ª  á­¨§ã
; BUF2D_OPT_CROP_RIGHT - ®¡à¥§ª  á¯à ¢ 
align 4
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
locals
	crop_r dd ?
endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .24end_f

	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
	jae .24no_crop_bottom
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov ecx,buf2d_h
		cmp ecx,1
		jle .24no_crop_bottom ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov ebx,buf2d_w
		imul ecx,ebx
		lea esi,[ecx+ecx*2] ;esi=3*ecx
		add esi,buf2d_data
		cld
		@@:
			sub esi,3
			cmp word[esi],ax
			jne @f
			cmp byte[esi+2],dl
			jne @f
			loop @b
		@@:
		lea ebx,[ebx+ebx*2]
		xor edx,edx
		mov eax,buf2d_h
		imul eax,ebx
		add eax,buf2d_data ;eax - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		@@:
			add esi,ebx
			cmp esi,eax
			jge @f
			inc edx ;¢ëç¨á«ï¥¬ ç¨á«® ¯®«­ëå áâப ¤«ï ®¡à¥§ ­¨ï
			loop @b
		@@:
		cmp edx,0
		je .24no_crop_bottom
			cmp edx,buf2d_h
			jge .24no_crop_bottom ;çâ®-¡ë ­¥ ¯®«ãç¨âì ¯ãá⮩ ¡ãä¥à
			sub buf2d_h,edx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			mov ecx,buf2d_h
			imul ecx,ebx ;ecx = ­®¢ë© à §¬¥à ¨§®¡à ¦¥­¨ï
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.24no_crop_bottom:

	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
	jae .24no_crop_top
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov esi,buf2d_data
		mov ecx,buf2d_h
		cmp ecx,1
		jle .24no_crop_top ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		dec ecx ;¯à¨ ®¡à¥§ ­¨¨ ¤®«¦­  ®áâ âìáï ¬¨­¨¬ã¬ 1-­  áâப  ¯¨ªá¥«¥©
		mov ebx,buf2d_w
		imul ecx,ebx
		cld
		@@:
			cmp word[esi],ax
			jne @f
			cmp byte[esi+2],dl
			jne @f
			add esi,3
			loop @b
		@@:
		lea ebx,[ebx+ebx*2]
		xor edx,edx
		@@:
			sub esi,ebx
			cmp esi,buf2d_data
			jl @f
			inc edx ;¢ëç¨á«ï¥¬ ç¨á«® ¯®«­ëå áâப ¤«ï ®¡à¥§ ­¨ï
			loop @b
		@@:
		cmp edx,0
		je .24no_crop_top
			xor eax,eax
			sub eax,edx
			mov ebx,buf2d_h
			sub ebx,edx
			stdcall buf_offset_h, edi, eax, edx, ebx ;ᤢ¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢ ¡ãä¥à¥ ¢¢¥àå (eax<0)
			sub buf2d_h,edx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			mov ecx,buf2d_h
			add buf2d_t,dx ;ᤢ¨£ ¥¬ ®âáâ㯠¢­¨§, ­  ç¨á«® ®¡à¥§ ­­ëå áâப
			mov ebx,buf2d_w
			imul ecx,ebx
			lea ecx,[ecx+ecx*2]
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.24no_crop_top:

	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
	jae .24no_crop_right
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov ebx,buf2d_w
		cmp ebx,1
		jle .24no_crop_right ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		lea ebx,[ebx+ebx*2]
		mov esi,ebx
		imul esi,buf2d_h
		add esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		mov dword[crop_r],0
		cld
		.24found_beg_right:
		sub esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp word[esi],ax
			jne .24found_right
			cmp byte[esi+2],dl
			jne .24found_right
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			loop @b
		inc dword[crop_r]

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jge .24found_right

		sub esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			cmp word[esi],ax
			jne .24found_right
			cmp byte[esi+2],dl
			jne .24found_right
			loop @b
		inc dword[crop_r]

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jl .24found_beg_right

		.24found_right:
		cmp dword[crop_r],0
		je .24no_crop_right
			mov ecx,buf2d_w
			sub ecx,dword[crop_r]
			stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			lea ecx,[ecx+ecx*2]
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.24no_crop_right:

	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
	jae .24no_crop_left
		mov eax,dword[color]
		mov edx,eax ;ax = colors - r,g
		shr edx,16 ;dl = color - b
		mov ebx,buf2d_w
		cmp ebx,1
		jle .24no_crop_left ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		lea ebx,[ebx+ebx*2]
		mov esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ­ ç®«® ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		mov dword[crop_r],0
		cld
		.24found_beg_left:

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp word[esi],ax
			jne .24found_left
			cmp byte[esi+2],dl
			jne .24found_left
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			loop @b
		inc dword[crop_r]
		add esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jge .24found_left

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			cmp word[esi],ax
			jne .24found_left
			cmp byte[esi+2],dl
			jne .24found_left
			loop @b
		inc dword[crop_r]
		add esi,3 ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp dword[crop_r],ecx
		jl .24found_beg_left

		.24found_left:
		cmp dword[crop_r],0
		je .24no_crop_left
			mov ecx,buf2d_w
			sub ecx,dword[crop_r]
			stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			lea ecx,[ecx+ecx*2]
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
			mov eax,dword[crop_r]
			add buf2d_l,ax
	.24no_crop_left:

	.24end_f:


	cmp buf2d_bits,8
	jne .8end_f

	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
	jae .8no_crop_bottom
		mov eax,dword[color]
		mov esi,buf2d_data
		mov ecx,buf2d_h
		cmp ecx,1
		jle .8no_crop_bottom ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov ebx,buf2d_w
		imul ecx,ebx
		mov esi,ecx
		add esi,buf2d_data
		cld
		@@:
			dec esi
			cmp byte[esi],al
			jne @f
			loop @b
		@@:
		xor edx,edx
		mov eax,buf2d_h
		imul eax,ebx
		add eax,buf2d_data ;eax - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		@@:
			add esi,ebx
			cmp esi,eax
			jge @f
			inc edx
			loop @b
		@@:
		cmp edx,0
		je .8no_crop_bottom
			cmp edx,buf2d_h
			jge .8no_crop_bottom ;çâ®-¡ë ­¥ ¯®«ãç¨âì ¯ãá⮩ ¡ãä¥à
			sub buf2d_h,edx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			mov ecx,buf2d_h
			imul ecx,ebx ;ecx = ­®¢ë© à §¬¥à ¨§®¡à ¦¥­¨ï
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.8no_crop_bottom:

	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
	jae .8no_crop_top
		mov eax,dword[color]
		mov esi,buf2d_data
		mov ecx,buf2d_h
		cmp ecx,1
		jle .8no_crop_top ;¯à®¢¥à塞 ­  á«ãç © ¥á«¨ ¢ëá®â  ¡ãä¥à  1 ¯¨ªá¥«ì
		dec ecx ;¯à¨ ®¡à¥§ ­¨¨ ¤®«¦­  ®áâ âìáï ¬¨­¨¬ã¬ 1-­  áâப  ¯¨ªá¥«¥©
		mov ebx,buf2d_w
		imul ecx,ebx
		cld
		@@:
			cmp byte[esi],al
			jne @f
			inc esi
			loop @b
		@@:
		xor edx,edx
		@@:
			sub esi,ebx
			cmp esi,buf2d_data
			jl @f
			inc edx
			loop @b
		@@:
		cmp edx,0
		je .8no_crop_top
			xor eax,eax
			sub eax,edx
			mov ebx,buf2d_h
			sub ebx,edx
			stdcall buf_offset_h, edi, eax, edx, ebx
			mov ecx,buf2d_h
			sub ecx,edx
			mov buf2d_h,ecx ;㬥­ìè ¥¬ ¢ëá®âã ¡ãä¥à 
			add buf2d_t,dx ;ᤢ¨£ ¥¬ ®âáâ㯠¢­¨§, ­  ç¨á«® ®¡à¥§ ­­ëå áâப
			mov ebx,buf2d_w
			imul ecx,ebx
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.8no_crop_top:

	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
	jae .8no_crop_right
		mov eax,dword[color]
		mov ebx,buf2d_w
		cmp ebx,1
		jle .8no_crop_right ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov esi,ebx
		imul esi,buf2d_h
		add esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ª®­¥æ ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		xor edx,edx
		cld

		.8found_beg:
		dec esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp byte[esi],al
			jne .8found
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			loop @b
		inc edx
		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jge .8found

		dec esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢«¥¢®
		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			cmp byte[esi],al
			jne .8found
			loop @b
		inc edx

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jl .8found_beg

		.8found:
		cmp edx,0
		je .8no_crop_right
			mov ecx,buf2d_w
			sub ecx,edx
			stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.8no_crop_right:

	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
	jae .8no_crop_left
		mov eax,dword[color]
		mov ebx,buf2d_w
		cmp ebx,1
		jle .8no_crop_left ;­  á«ãç © ¥á«¨ è¨à¨­  ¡ãä¥à  1 ¯¨ªá¥«ì
		mov esi,buf2d_data ;esi - 㪠§ â¥«ì ­  ­ ç®«® ¡ãä¥à  ¨§®¡à ¦¥­¨ï
		mov edx,0
		cld
		.8found_beg_left:

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			cmp word[esi],ax
			jne .8found_left
			add esi,ebx ;¯à룠¥¬ ­  ­¨¦­îî áâபã
			loop @b
		inc edx
		inc esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jge .8found_left

		mov ecx,buf2d_h ;¢®ááâ ­®¢«¥­¨¥ ecx ¤«ï ­®¢®£® 横« 
		@@:
			sub esi,ebx ;¯à룠¥¬ ­  ¢¥àå­îî áâபã
			cmp word[esi],ax
			jne .8found_left
			loop @b
		inc edx
		inc esi ;¤¢¨£ ¥¬áï ­  1-­ã ª®«®­ªã ¢¯à ¢®

		mov ecx,buf2d_w
		dec ecx ;1 ª®«®­ª  ­  § ¯ á
		cmp edx,ecx
		jl .8found_beg_left

		.8found_left:
		cmp edx,0
		je .8no_crop_left
			mov ecx,buf2d_w
			sub ecx,edx
			stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;®¡à¥§ ¥¬ ¡ãä¥à, ¯® ­®¢®¬ã à §¬¥àã
			mov buf2d_w,ecx ;áâ ¢¨¬ ­®¢ãî è¨à¨­ã ¤«ï ¡ãä¥à 
			mov ebx,buf2d_h
			imul ecx,ebx
			invoke mem.realloc,buf2d_data,ecx
			mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
			mov eax,edx
			add buf2d_l,ax
	.8no_crop_left:

	.8end_f:

	popad
	ret
endp

;®¡à¥§ ¥¬ 梥⭮¥ ¨§®¡à ¦¥­¨¥ á ¯à ¢®© áâ®à®­ë
;input:
;data_rgb - pointer to rgb data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov eax, dword[size_w_old]
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
	mov ebx, dword[size_w_new]
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
	mov edx, dword[size_h]
	mov edi, dword[data_rgb] ;edi - ¯®«ã砥⠤ ­­ë¥
	mov esi, edi
	add edi, ebx
	add esi, eax
	cld
	@@:
		dec edx ;㬥­ìè ¥¬ áç¥â稪 ®áâ ¢è¨åáï áâப ­  1
		cmp edx,0
		jle @f
		mov ecx, ebx
		rep movsb ;¯¥à¥­®á (ª®¯¨à®¢ ­¨¥) áâப¨ ¯¨ªá¥«¥©
		add esi,eax ;¯¥à¥å®¤ ­  ­®¢ãî áâà®çªã ¨§®¡à ¦¥­¨ï
		sub esi,ebx
		jmp @b
	@@:
	popad
	ret
endp

;®¡à¥§ ¥¬ á¥à®¥ ¨§®¡à ¦¥­¨¥ á ¯à ¢®© áâ®à®­ë
;input:
;data_gray - pointer to gray data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov eax, dword[size_w_old]
	mov ebx, dword[size_w_new]
	mov edx, dword[size_h]
	mov edi, dword[data_gray] ;edi - ¯®«ã砥⠤ ­­ë¥
	mov esi, edi
	add edi, ebx
	add esi, eax
	cld
	@@:
		dec edx ;㬥­ìè ¥¬ áç¥â稪 ®áâ ¢è¨åáï áâப ­  1
		cmp edx,0
		jle @f
		mov ecx, ebx
		rep movsb ;¯¥à¥­®á (ª®¯¨à®¢ ­¨¥) áâப¨ ¯¨ªá¥«¥©
		add esi,eax ;¯¥à¥å®¤ ­  ­®¢ãî áâà®çªã ¨§®¡à ¦¥­¨ï
		sub esi,ebx
		jmp @b
	@@:
	popad
	ret
endp

;®¡à¥§ ¥¬ 梥⭮¥ ¨§®¡à ¦¥­¨¥ á «¥¢®© áâ®à®­ë
;input:
;data_rgb - pointer to rgb data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov edi,dword[data_rgb]
	mov esi,edi
	mov eax,dword[size_w_old]
	mov ebx,dword[size_w_new]
	cmp eax,ebx
	jle .end_f ;áâ àë© à §¬¥à ¨§®¡à ¦¥­¨ï ­¥ ¬®¦¥â ¡ëâì ¬¥­ìè¥ ­®¢®£® (¯à¨ ãá«®¢¨¨ ®¡à¥§ ­¨ï ª à⨭ª¨)
		lea eax,[eax+eax*2]
		lea ebx,[ebx+ebx*2]
		sub eax,ebx
		mov edx,dword[size_h] ;¢ëá®â  ¨§®¡à ¦¥­¨ï
		cld
		@@:
			add esi,eax
			mov ecx,ebx
			rep movsb
			dec edx
			cmp edx,0
			jg @b
	.end_f:
	popad
	ret
endp

;®¡à¥§ ¥¬ á¥à®¥ ¨§®¡à ¦¥­¨¥ á «¥¢®© áâ®à®­ë
;input:
;data_gray - pointer to gray data
;size_w_old - width img in pixels
;size_w_new - new width img in pixels
;size_h - height img in pixels
align 4
proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
	pushad
	mov edi,dword[data_gray]
	mov esi,edi
	mov eax,dword[size_w_old]
	mov ebx,dword[size_w_new]
	cmp eax,ebx
	jle .end_f ;áâ àë© à §¬¥à ¨§®¡à ¦¥­¨ï ­¥ ¬®¦¥â ¡ëâì ¬¥­ìè¥ ­®¢®£® (¯à¨ ãá«®¢¨¨ ®¡à¥§ ­¨ï ª à⨭ª¨)
		sub eax,ebx
		mov edx,dword[size_h] ;¢ëá®â  ¨§®¡à ¦¥­¨ï
		cld
		@@:
			add esi,eax
			mov ecx,ebx
			rep movsb
			dec edx
			cmp edx,0
			jg @b
	.end_f:
	popad
	ret
endp

;hoffs - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ­  ª®âàë¥ ¯®¤­¨¬ ¥âáï/®¯ã᪠¥âáï ¨§®¡à ¦¥­¨¥
;img_t - ¢ëá®â , á ª®â®à®© ­ ç¨­ ¥âáï ¤¢¨£ îé ïáï ç áâì ¨§®¡à ¦¥­¨ï
align 4
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;ᤢ¨£ ¥â ¨§®¡à ¦¥­¨¥ ¯® ¢ëá®â¥
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .end_move_24

	mov eax,[hoffs]
	cmp eax,0
	je .end_move_24
		mov ebx,buf2d_w
		mov edx,dword[img_t]
			mov ecx,dword[img_h] ;ecx - ¢ëá®â  ᤢ¨£ ¥¬ëå ¤ ­­ëå
			cmp ecx,buf2d_h
			jge .end_f ;®è¨¡®ç­®¥ ãá«®¢¨¥, ¢ëá®â  ¨§®¡à ¦¥­¨ï ¬¥­ìè¥ ç¥¬ ¢ëá®â  ᤢ¨£ ¥¬®£® ¨§®¡à ¦¥­¨ï
			imul ecx,ebx ;ecx - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ ᤢ¨£ ¥¬ëå ¤ ­­ëå
			lea ecx,[ecx+ecx*2]
		imul ebx,edx
		lea ebx,[ebx+ebx*2]
		mov esi,buf2d_data
		add esi,ebx

		add edx,eax ;edx = img_t+hoffs (hoffs<0)
		mov ebx,buf2d_w
		imul ebx,edx
		lea ebx,[ebx+ebx*2]
		mov edi,buf2d_data ;¯®§¨æ¨ï, ªã¤  ¡ã¤¥â ¤¢¨£ âìáï ¨§®¡à ¦¥­¨¥
		add edi,ebx

		cmp eax,0
		jg .move_down_24
			;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢¢¥àå
			cld
			rep movsb
			jmp .end_f
		.move_down_24:
			;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢­¨§
			add esi,ecx
			dec esi
			add edi,ecx
			dec edi
			std
			rep movsb
			jmp .end_f
	.end_move_24:

;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b

	cmp buf2d_bits,8
	jne .end_move_8

	mov eax,[hoffs]
	cmp eax,0
	je .end_move_8
		;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢¢¥àå
		mov ebx,buf2d_w
		mov edx,dword[img_t]
			mov ecx,dword[img_h] ;ecx - ¢ëá®â  ᤢ¨£ ¥¬ëå ¤ ­­ëå
			cmp ecx,buf2d_h
			jge .end_f ;®è¨¡®ç­®¥ ãá«®¢¨¥, ¢ëá®â  ¨§®¡à ¦¥­¨ï ¬¥­ìè¥ ç¥¬ ¢ëá®â  ᤢ¨£ ¥¬®£® ¨§®¡à ¦¥­¨ï
			imul ecx,ebx ;ecx - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ ᤢ¨£ ¥¬ëå ¤ ­­ëå
		imul ebx,edx
		mov esi,buf2d_data
		add esi,ebx

		add edx,eax ;edx = img_t+hoffs (hoffs<0)
		mov ebx,buf2d_w
		imul ebx,edx
		mov edi,buf2d_data ;¯®§¨æ¨ï, ªã¤  ¡ã¤¥â ¤¢¨£ âìáï ¨§®¡à ¦¥­¨¥
		add edi,ebx

		cmp eax,0
		jg .move_down_8
			cld
			rep movsb
			jmp .end_f
		.move_down_8:
			;¤¢¨£ ¥¬ ¨§®¡à ¦¥­¨¥ ¢­¨§
			add esi,ecx
			dec esi
			add edi,ecx
			dec edi
			std
			rep movsb
			jmp .end_f
	.end_move_8:

	.end_f:
	popad
	ret
endp


align 4
proc buf_draw_buf, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error
		mov eax,7
		mov ebx,buf2d_data

		mov ecx,buf2d_w
		ror ecx,16
		mov edx,buf2d_h
		mov cx,dx

		mov edx,buf2d_size_lt
		ror edx,16
		int 0x40
		jmp .end_draw_24
	.error:
		stdcall print_err,sz_buf2d_draw,txt_err_n24b
	.end_draw_24:
	popad
	ret
endp

align 4
proc buf_delete, buf_struc:dword
	push eax edi
	mov edi,dword[buf_struc]
	invoke mem.free,buf2d_data
	pop edi eax
	ret
endp

align 4
proc buf_resize, buf_struc:dword, new_w:dword, new_h:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .24bit
		mov eax,dword[new_w]
		cmp eax,1
		jl @f
			mov buf2d_w,eax
		@@:
		mov ecx,buf2d_w
		mov eax,dword[new_h]
		cmp eax,1
		jl @f
			mov buf2d_h,eax
		@@:
		mov ebx,buf2d_h
		imul ecx,ebx
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
		invoke mem.realloc,buf2d_data,ecx ;¨§¬¥­ï¥¬ ¯ ¬ïâì § ­¨¬ ¥¬ãî ¡ãä¥à®¬
		mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
	.24bit:
	popad
	ret
endp

align 4
rot_table: ;â ¡«¨æ  ¤«ï 㪠§ ­¨ï ­  ¯®¤ä㭪樨 ¤«ï ¯®¢®à®â®¢
	dd buf_rotate.8b90,buf_rotate.24b90,buf_rotate.32b90,\
	buf_rotate.8b180,buf_rotate.24b180,buf_rotate.32b180

;¯®¢®à®â ¨§®¡à ¦¥­¨ï ­  90 ¨«¨ 180 £à ¤ãᮢ
align 4
proc buf_rotate, buf_struc:dword, angle:dword
locals
	n_data dd ?
	dec_h dd ? ;ç¨á«® ¡ ©â, ¤«ï 㬥­ì襭¨ï ª®®à¤¨­ âë y
endl
	pushad
	mov edi,[buf_struc]
	mov ebx,buf2d_w
	mov ecx,buf2d_h

	lea eax,[rot_table]
	cmp dword[angle],90 ;¯à®¢¥àª  㣫  ¯®¢®à®â 
	je .beg_0
	cmp dword[angle],180
	jne @f
		add eax,12
		jmp .beg_0
	@@:
	jmp .end_f
	.beg_0: ;¯à®¢¥àª  ¡¨â­®á⨠¡ãä¥à 
	cmp buf2d_bits,8
	jne @f
		jmp dword[eax]
	@@:
	cmp buf2d_bits,24
	jne @f
		add eax,4
		jmp dword[eax]
	@@:
	cmp buf2d_bits,32
	jne @f
		add eax,8
		jmp dword[eax]
	@@:
	jmp .end_f

	.8b90: ;¯®¢®à®â 8 ¡¨â­®£® ¡ãä¥à  ­  90 £à ¤ãᮢ
		mov edx,ecx ;edx - buf_h
		imul ecx,ebx
		invoke mem.alloc,ecx ;¢ë¤¥«ï¥¬ ¢à¥¬¥­­ãî ¯ ¬ïâì
		cmp eax,0
		je .end_f
		mov [n_data],eax
		mov [dec_h],ecx
		inc dword[dec_h]

		;copy buf --> mem
		mov edi,[buf_struc]
		mov esi,buf2d_data
		mov edi,eax ;[n_data]
		dec edx ;ª®à¥ªâ¨à㥬 edx ­  1 ¡ ©â, ¤«ï ª®¬¯¥­á æ¨¨ ᤢ¨£  ¢ movsb
		add edi,edx
		xor eax,eax
		cld
		.cycle_0:
			movsb
			add edi,edx
			inc eax
			cmp eax,ebx
			jl @f
				xor eax,eax
				sub edi,[dec_h]
			@@:
			loop .cycle_0

		;change buf_w <---> buf_h
		mov esi,[n_data]
		mov edi,[buf_struc]
		mov edi,buf2d_data
		mov ecx,ebx
		inc edx ;¨á¯à ¢«ï¥¬ ᪮४â¨à®¢ ­­ë© edx
		imul ecx,edx
		;copy buf <-- mem
		;cld
		rep movsb
		invoke mem.free,[n_data]
		jmp .change_w_h
	.24b90: ;¯®¢®à®â 24 ¡¨â­®£® ¡ãä¥à  ­  90 £à ¤ãᮢ
		mov esi,ecx
		imul esi,ebx
		lea ecx,[ecx+ecx*2]
		mov edx,ecx ;edx - buf_h * 3
		imul ecx,ebx
		invoke mem.alloc,ecx ;¢ë¤¥«ï¥¬ ¢à¥¬¥­­ãî ¯ ¬ïâì
		cmp eax,0
		je .end_f
		mov [n_data],eax
		mov [dec_h],ecx
		add dword[dec_h],3

		;copy buf --> mem
		
		mov edi,[buf_struc]
		mov ecx,esi
		mov esi,buf2d_data
		mov edi,eax ;[n_data]
		sub edx,3 ;ª®à¥ªâ¨à㥬 edx ­  3 ¡ ©â , ¤«ï ª®¬¯¥­á æ¨¨ ᤢ¨£ 
		add edi,edx
		xor eax,eax
		cld
		.cycle_1:
			movsw
			movsb
			add edi,edx
			inc eax
			cmp eax,ebx
			jl @f
				xor eax,eax
				sub edi,[dec_h]
			@@:
			loop .cycle_1

		;copy buf <-- mem
		mov esi,[n_data]
		mov edi,[buf_struc]
		mov edi,buf2d_data
		mov ecx,ebx
		add edx,3 ;¨á¯à ¢«ï¥¬ ᪮४â¨à®¢ ­­ë© edx
		imul ecx,edx
		;cld
		rep movsb
		invoke mem.free,[n_data]
		jmp .change_w_h
	.32b90: ;¯®¢®à®â 32 ¡¨â­®£® ¡ãä¥à  ­  90 £à ¤ãᮢ
		shl ecx,2
		mov edx,ecx ;edx - buf_h * 4
		imul ecx,ebx
		invoke mem.alloc,ecx ;¢ë¤¥«ï¥¬ ¢à¥¬¥­­ãî ¯ ¬ïâì
		cmp eax,0
		je .end_f
		mov [n_data],eax
		mov [dec_h],ecx
		add dword[dec_h],4

		;copy buf --> mem
		mov edi,[buf_struc]
		shr ecx,2
		mov esi,buf2d_data
		mov edi,eax ;[n_data]
		sub edx,4 ;ª®à¥ªâ¨à㥬 edx ­  4 ¡ ©â , ¤«ï ª®¬¯¥­á æ¨¨ ᤢ¨£  ¢ movsd
		add edi,edx
		xor eax,eax
		cld
		.cycle_2:
			movsd
			add edi,edx
			inc eax
			cmp eax,ebx
			jl @f
				xor eax,eax
				sub edi,[dec_h]
			@@:
			loop .cycle_2

		;copy buf <-- mem
		mov esi,[n_data]
		mov edi,[buf_struc]
		mov edi,buf2d_data
		mov ecx,ebx
		add edx,4 ;¨á¯à ¢«ï¥¬ ᪮४â¨à®¢ ­­ë© edx
		imul ecx,edx
		shr ecx,2
		;cld
		rep movsd
		invoke mem.free,[n_data]
		;jmp .change_w_h
	.change_w_h: ;change buf_w <---> buf_h
		mov edi,[buf_struc]
		mov eax,buf2d_w
		mov ebx,buf2d_h
		mov buf2d_h,eax
		mov buf2d_w,ebx
		jmp .end_f
	.8b180: ;¯®¢®à®â 8 ¡¨â­®£® ¡ãä¥à  ­  180 £à ¤ãᮢ
		mov edi,buf2d_data
		mov esi,edi
		imul ecx,ebx
		add esi,ecx
		dec esi
		shr ecx,1 ;ecx - ç¨á«® ¯¨ªá¥«¥© ¡ãä¥à  : 2
		std
		@@:
			lodsb
			mov ah,byte[edi]
			mov byte[esi+1],ah
			mov byte[edi],al
			inc edi
			loop @b
			jmp .end_f
	.24b180: ;¯®¢®à®â 24 ¡¨â­®£® ¡ãä¥à  ­  180 £à ¤ãᮢ
		mov esi,buf2d_data
		mov edi,esi
		imul ecx,ebx
		mov eax,ecx
		lea ecx,[ecx+ecx*2]
		add edi,ecx
		sub edi,3
		shr eax,1
		mov ecx,eax ;ecx - ç¨á«® ¯¨ªá¥«¥© ¡ãä¥à  : 2
		cld
		@@:
			lodsw
			mov edx,eax
			lodsb
			mov bx,word[edi]
			mov word[esi-3],bx
			mov bl,byte[edi+2]
			mov byte[esi-1],bl
			mov byte[edi+2],al
			mov word[edi],dx
			sub edi,3
			loop @b
			jmp .end_f
	.32b180: ;¯®¢®à®â 32 ¡¨â­®£® ¡ãä¥à  ­  180 £à ¤ãᮢ
		mov edi,buf2d_data
		mov esi,edi
		imul ecx,ebx
		shl ecx,2
		add esi,ecx
		sub esi,4
		shr ecx,3 ;ecx - ç¨á«® ¯¨ªá¥«¥© ¡ãä¥à  : 2
		std
		@@:
			lodsd
			mov ebx,dword[edi]
			mov dword[esi+4],ebx
			mov dword[edi],eax
			add edi,4
			loop @b
		;jmp .end_f

	.end_f:
	popad
	ret
endp

align 4
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
locals
	loc_1 dd ?
	loc_2 dd ?
	napravl db ?
endl
	pushad
		mov eax,dword[coord_x1]
		sub eax,dword[coord_x0]
		bt eax,31
		jae @f
			neg eax
			inc eax
		@@:
		mov ebx,dword[coord_y1]
		sub ebx,dword[coord_y0]
		jnz @f
			;¥á«¨ § ¤ ­  £®à¨§®­â «ì­ ï «¨­¨ï y0=y1
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
			jmp .coord_end
		@@:
		bt ebx,31
		jae @f
			neg ebx
			inc ebx
		@@:
		mov edx,dword[color]

		mov [napravl],byte 0 ;bool steep=false
		cmp eax,ebx
		jle @f
			mov [napravl],byte 1 ;bool steep=true
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
		@@:
		mov eax,dword[coord_y0] ;x0
		cmp eax,dword[coord_y1] ;if(x0>x1)
		jle @f
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
		@@:

; int deltax esi
; int deltay edi
; int error  ebp-6
; int ystep  ebp-8

		mov eax,dword[coord_y0]
		mov esi,dword[coord_y1]
		sub esi,eax ;deltax = y1-y0
		mov ebx,esi
		shr ebx,1
		mov [loc_1],ebx ;error = deltax/2

		mov eax,dword[coord_x0]
		mov edi,dword[coord_x1]
		mov [loc_2],dword -1 ;ystep = -1
		cmp eax,edi ;if (x0<x1) ystep = 1;
		jge @f
			mov [loc_2],dword 1 ;ystep = 1
		@@:
		sub edi,eax ;x1-x0

		bts edi,31
		jae @f
			neg edi
			inc edi
		@@:
		and edi,0x7fffffff ;deltay = abs(x1-x0)

		mov eax,edi
		mov edi,[buf_struc]
		cmp buf2d_bits,8
		je @f
		cmp buf2d_bits,24
		je @f
			jmp .coord_end
		@@:

		cmp [napravl],0
		jne .coord_yx
			mov ebx,dword[coord_x0]
			mov ecx,dword[coord_y0]

			@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
				cmp ecx,dword[coord_y1]
				jg @f ;jge ???
				call draw_pixel

				sub dword[loc_1],eax ;error -= deltay
				cmp dword[loc_1],0 ;if(error<0)
				jge .if0
					add ebx,[loc_2] ;y += ystep
					add [loc_1],esi ;error += deltax
				.if0:
				inc ecx
				jmp @b
			@@:
			jmp .coord_end
		.coord_yx:
			mov ebx,dword[coord_y0]
			mov ecx,dword[coord_x0]

			@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
				cmp ebx,dword[coord_y1]
				jg @f ;jge ???
				call draw_pixel

				sub dword[loc_1],eax ;error -= deltay
				cmp dword[loc_1],0 ;if(error<0)
				jge .if1
					add ecx,[loc_2] ;y += ystep
					add [loc_1],esi ;error += deltax
				.if1:
				inc ebx
				jmp @b
			@@:
	.coord_end:
	popad
	ret
endp

;à¨á®¢ ­¨¥ ᣫ ¦¥­­®© «¨­¨¨
align 4
proc buf_line_brs_sm, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
locals
	loc_1 dd ?
	loc_2 dd ?
	napravl db ?
endl
	pushad
		mov eax,dword[coord_x1]
		sub eax,dword[coord_x0]
		bt eax,31
		jae @f
			neg eax
			inc eax
		@@:
		mov ebx,dword[coord_y1]
		sub ebx,dword[coord_y0]
		jnz @f
			;¥á«¨ § ¤ ­  £®à¨§®­â «ì­ ï «¨­¨ï y0=y1
			stdcall buf_line_h, [buf_struc], [coord_x0], [coord_y0], [coord_x1], [color]
			jmp .coord_end
		@@:
		bt ebx,31
		jae @f
			neg ebx
			inc ebx
		@@:
		mov edx,dword[color]

		mov [napravl],byte 0 ;bool steep=false
		cmp eax,ebx
		jle @f
			mov [napravl],byte 1 ;bool steep=true
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
		@@:
		mov eax,dword[coord_y0] ;x0
		cmp eax,dword[coord_y1] ;if(x0>x1)
		jle @f
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
		@@:

; int deltax esi
; int deltay edi
; int error  ebp-6
; int ystep  ebp-8

		mov eax,dword[coord_y0]
		mov esi,dword[coord_y1]
		sub esi,eax ;deltax = y1-y0
		mov ebx,esi
		shr ebx,1
		mov [loc_1],ebx ;error = deltax/2

		mov eax,dword[coord_x0]
		mov edi,dword[coord_x1]
		mov [loc_2],dword -1 ;ystep = -1
		cmp eax,edi ;if (x0<x1) ystep = 1;
		jge @f
			mov [loc_2],dword 1 ;ystep = 1
		@@:
		sub edi,eax ;x1-x0

		bts edi,31
		jae @f
			neg edi
			inc edi
		@@:
		and edi,0x7fffffff ;deltay = abs(x1-x0)

		mov eax,edi
		mov edi,[buf_struc]
		cmp buf2d_bits,24
		jne .coord_end

		cmp [napravl],0
		jne .coord_yx
			mov ebx,dword[coord_x0]
			mov ecx,dword[coord_y0]

			@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
				cmp ecx,dword[coord_y1]
				jg @f ;jge ???
				push eax
					mov eax,esi
					sub eax,[loc_1]
					stdcall draw_pixel_transp, eax,esi
				pop eax
				add ebx,[loc_2]
				stdcall draw_pixel_transp, [loc_1],esi
				sub ebx,[loc_2]

				sub dword[loc_1],eax ;error -= deltay
				cmp dword[loc_1],0 ;if(error<0)
				jge .if0
					add ebx,[loc_2] ;y += ystep
					add [loc_1],esi ;error += deltax
				.if0:
				inc ecx
				jmp @b
			@@:
			jmp .coord_end
		.coord_yx:
			mov ebx,dword[coord_y0]
			mov ecx,dword[coord_x0]

			@@: ;for (x=x0 ; x<x1; x++) ;------------------------------------
				cmp ebx,dword[coord_y1]
				jg @f ;jge ???
				push eax
					mov eax,esi
					sub eax,[loc_1]
					stdcall draw_pixel_transp, eax,esi
				pop eax
				add ecx,[loc_2]
				stdcall draw_pixel_transp, [loc_1],esi
				sub ecx,[loc_2]

				sub dword[loc_1],eax ;error -= deltay
				cmp dword[loc_1],0 ;if(error<0)
				jge .if1
					add ecx,[loc_2] ;y += ystep
					add [loc_1],esi ;error += deltax
				.if1:
				inc ebx
				jmp @b
			@@:
	.coord_end:
	popad
	ret
endp

;à¨á®¢ ­¨¥ £®à¨§®­â «ì­®© «¨­¨¨, ¯®â®¬ã ­¥â ¯ à ¬¥âà  coord_y1
align 4
proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
	pushad
	pushfd
		mov edi,[buf_struc]
		cmp buf2d_bits,8
		je @f
		cmp buf2d_bits,24
		je @f
			jmp .end24
		@@: ;®¯à¥¤¥«¥­¨¥ ª®®à¤¨­ â «¨­¨¨ ®â­®á¨â¥«ì­® ¡ãä¥à 

		mov ecx,dword[coord_y0]
		bt ecx,31
		jc .end24 ;¥á«¨ ª®®à¤¨­ â  y0 ®âà¨æ â¥«ì­ ï
		cmp ecx,buf2d_h
		jge .end24 ;¥á«¨ ª®®à¤¨­ â  y0 ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 

		mov ebx,dword[coord_x0]
		mov esi,dword[coord_x1]
		cmp ebx,esi
		jle @f
			xchg ebx,esi ;¥á«¨ x0 > x1 â® ¬¥­ï¥¬ ¬¥áâ ¬¨ x0 ¨ x1
		@@:
		bt ebx,31
		jae @f
			;¥á«¨ ª®®à¤¨­ â  x0 ®âà¨æ â¥«ì­ ï
			xor ebx,ebx
		@@:
		cmp esi,buf2d_w
		jl @f
			;¥á«¨ ª®®à¤¨­ â  x0 ¡®«ìè¥ è¨à¨­ë ¡ãä¥à 
			mov esi,buf2d_w
			dec esi
		@@:
		cmp ebx,esi
		jg .end24 ;¥á«¨ x0 > x1 ¬®¦¥â ¢®§­¨ª­ãâì ª®£¤  ®¡¥ ª®®à¤¨­ âë x0, x1 ­ å®¤¨«¨áì §  ®¤­¨¬ ¨§ ¯à¥¤¥«®¢ ¡ãä¥à 

		cmp buf2d_bits,24
		je .beg24
			;à¨á®¢ ­¨¥ ¢ 8 ¡¨â­®¬ ¡ãä¥à¥
			;¢ edx ¢ëç¨á«ï¥¬ ­ ç «® 1-© â®çª¨ «¨­¨¨ ¢ ¡ãä¥à¥ ¨§®¡à ¦¥­¨ï
			mov edx,buf2d_w ;size x
			imul edx,ecx ;size_x*y
			add edx,ebx	 ;size_x*y+x
			add edx,buf2d_data ;ptr+(size_x*y+x)
			mov edi,edx ;⥯¥àì ¬®¦¥¬ ¯®àâ¨âì 㪠§ â¥«ì ­  ¡ãä¥à

			mov ecx,esi
			sub ecx,ebx ;¢ ecx ª®««¨ç¥á⢮ â®ç¥ª «¨­¨¨ ¢ë¢®¤¨¬ëå ¢ ¡ãä¥à
			inc ecx ;çâ®-¡ë ¯®á«¥¤­ïï â®çª  «¨­¨¨ â ª¦¥ ®â®¡à ¦ « áì
			mov eax,dword[color] ;¡ã¤¥¬ ¨á¯®«ì§®¢ âì ⮫쪮 §­ ç¥­¨¥ ¢ al
			cld
			rep stosb ;横« ¯® ®á¨ x ®â x0 ¤® x1 (¢ª«îç ï x1)
			jmp .end24

		.beg24: ;à¨á®¢ ­¨¥ ¢ 24 ¡¨â­®¬ ¡ãä¥à¥
		;¢ eax ¢ëç¨á«ï¥¬ ­ ç «® 1-© â®çª¨ «¨­¨¨ ¢ ¡ãä¥à¥ ¨§®¡à ¦¥­¨ï
		mov eax,buf2d_w ;size x
		imul eax,ecx ;size_x*y
		add eax,ebx	 ;size_x*y+x
		lea eax,[eax+eax*2] ;(size_x*y+x)*3
		add eax,buf2d_data  ;ptr+(size_x*y+x)*3

		mov ecx,esi
		sub ecx,ebx ;¢ ecx ª®««¨ç¥á⢮ â®ç¥ª «¨­¨¨ ¢ë¢®¤¨¬ëå ¢ ¡ãä¥à
		inc ecx ;çâ®-¡ë ¯®á«¥¤­ïï â®çª  «¨­¨¨ â ª¦¥ ®â®¡à ¦ « áì
		mov edx,dword[color]
		mov ebx,edx ;ª®®à¤¨­ â  x0 ¢ ebx 㦥 ­¥ ­ã¦­ 
		ror edx,16 ;¯®¢®à ç¨¢ ¥¬ ॣ¨áâà çâ® ¡ë 3-© ¡ ©â ¯®¯ « ¢ dl
		cld
		@@: ;横« ¯® ®á¨ x ®â x0 ¤® x1 (¢ª«îç ï x1)
			mov word[eax],bx ;copy pixel color
			mov byte[eax+2],dl
			add eax,3
			loop @b
		.end24:
	popfd
	popad
	ret
endp

align 4
proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
pushad
	mov edi,[buf_struc]
	cmp buf2d_bits,8
	je @f
	cmp buf2d_bits,24
	je @f
		jmp .coord_end
	@@:

		mov eax,[coord_x]
		mov ebx,[coord_y]
		mov ecx,[w]
		;cmp ecx,1
		;jl .coord_end
		cmp ecx,0
		je .coord_end
		jg @f
			add eax,ecx
			inc eax
			neg ecx
		@@:
		add ecx,eax
		dec ecx
		mov edx,[h]
		;cmp edx,1
		;jl .coord_end
		cmp edx,0
		je .coord_end
		jg @f
			add ebx,edx
			inc ebx
			neg edx
		@@:

		add edx,ebx
		dec edx
		mov esi,dword[color]
		stdcall buf_line_h, edi, eax, ebx, ecx, esi ;«¨­¨ï -
		stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;«¨­¨ï |
		stdcall buf_line_h, edi, eax, edx, ecx, esi ;«¨­¨ï -
		stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;«¨­¨ï |
	.coord_end:
popad
	ret
endp

align 4
proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
pushad
	mov edi,[buf_struc]
	cmp buf2d_bits,8
	je @f
	cmp buf2d_bits,24
	je @f
		jmp .coord_end
	@@:
		mov eax,[coord_x]
		mov ebx,[coord_y]
		mov edx,[w]
		cmp edx,0
		je .coord_end ;¥á«¨ ¢ëá®â  0 ¯¨ªá¥«¥©
		jg @f ;¥á«¨ ¢ëá®â  ¯®«®¦¨â¥«ì­ ï
			add eax,edx
			inc eax
			neg edx ;è¨à¨­ã ¤¥« ¥¬ ¯®«®¦¨â¥«ì­®©
			;inc edx ;¯®ç¥¬ã âãâ ­¥ ¤®¡ ¢«ï¥¬ 1-æã ï ­¥ §­ î, ­® á ­¥© à ¡®â ¥â ­¥ ¯à ¢¨«ì­®
		@@:
		add edx,eax
		dec edx
		mov ecx,[h]
		cmp ecx,0
		je .coord_end ;¥á«¨ ¢ëá®â  0 ¯¨ªá¥«¥©
		jg @f ;¥á«¨ ¢ëá®â  ¯®«®¦¨â¥«ì­ ï
			add ebx,ecx ;ᤢ¨£ ¥¬ ¢¥àå­îî ª®®à¤¨­ âã ¯àאַ㣮«ì­¨ª 
			inc ebx
			neg ecx ;¢ëá®âã ¤¥« ¥¬ ¯®«®¦¨â¥«ì­®©
			;inc ecx ;¯®ç¥¬ã âãâ ­¥ ¤®¡ ¢«ï¥¬ 1-æã ï ­¥ §­ î, ­® á ­¥© à ¡®â ¥â ­¥ ¯à ¢¨«ì­®
		@@:
		mov esi,dword[color]
		cld
		@@:
			stdcall buf_line_h, edi, eax, ebx, edx, esi ;«¨­¨ï -
			inc ebx
			loop @b
	.coord_end:
popad
	ret
endp

align 4
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
locals
	po_x dd ?
	po_y dd ?
endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,8
	je @f
	cmp buf2d_bits,24
	je @f
		jmp .error
	@@:
		mov edx,dword[color]

		finit
		fild dword[coord_x]
		fild dword[coord_y]
		fild dword[r]
		fldz ;px=0
		fld st1 ;py=r

		fldpi
		fmul st0,st3
		fistp dword[po_x]
		mov esi,dword[po_x] ;esi=pi*r
		shl esi,1 ;esi=2*pi*r

		;st0 = py
		;st1 = px
		;st2 = r
		;st3 = y
		;st4 = x

		@@:
			;Point(px + x, y - py)
			fld st1 ;st0=px
			fadd st0,st5 ;st0=px+x
			fistp dword[po_x]
			mov ebx,dword[po_x]
			fld st3 ;st0=y
			fsub st0,st1 ;st0=y-py
			fistp dword[po_y]
			mov ecx,dword[po_y]
			call draw_pixel
			;px += py/r
			fld st0 ;st0=py
			fdiv st0,st3 ;st0=py/r
			faddp st2,st0 ;st3+=st0
			;py -= px/r
			fld st1 ;st0=px
			fdiv st0,st3 ;st0=px/r
			fsubp st1,st0 ;st2-=st0

			dec esi
			cmp esi,0
			jge @b
		jmp .exit_fun
	.error:
		stdcall print_err,sz_buf2d_circle,txt_err_n8_24b
	.exit_fun:

	popad
	ret
endp

;äã­ªæ¨ï ¤«ï § «¨¢ª¨ ®¡« á⨠¢ë¡à ­­ë¬ 梥⮬
align 4
proc buf_flood_fill, buf_struc:dword, coord_x:dword, coord_y:dword, mode:dword, color_f:dword, color_b:dword
	pushad
		mov edi,[buf_struc]
		cmp buf2d_bits,24
		jne .end24

			mov ebx,dword[coord_x]
			mov ecx,dword[coord_y]
			mov edx,dword[color_f]
			mov esi,dword[color_b]

			cmp dword[mode],1 ;¢ § ¢¨á¨¬®á⨠®â 'mode' ®¯à¥¤¥«ï¥¬ ª ª¨¬  «£®à¨â¬®¬ ¡ã¤¥¬ ¯®«ì§®¢ âìáï
			je @f
				call buf_flood_fill_recurs_0 ;§ «¨¢ ¥¬ ¤® ¯¨ªá¥«¥© æ¢¥â  esi
				jmp .end24
			@@:
				call buf_flood_fill_recurs_1 ;§ «¨¢ ¥¬ ¯¨ªá¥«¨ ¨¬¥î騥 梥â esi

		.end24:
	popad
	ret
endp

;input:
; ebx = coord_x
; ecx = coord_y
; edx = 梥⠧ «¨¢ª¨
; esi = 梥⠣࠭¨æë, ¤® ª®â®à®© ¡ã¤¥â ¨â¨ § «¨¢ª 
; edi = buf_struc
;output:
; eax = ¯®àâ¨âáï
align 4
buf_flood_fill_recurs_0:
	call get_pixel_24
	cmp eax,0xffffffff ;if error coords
	je .end_fun
	cmp eax,edx ;¥á«¨ 梥⠯¨ªá¥«ï ᮢ¯ « á 梥⮬ § «¨¢ª¨, §­ ç¨â § «¨¢ª  ¢ í⮩ ®¡« á⨠㦥 ¡ë«  ᤥ« ­ 
	je .end_fun

		call draw_pixel

		dec ebx
		call get_pixel_24
		cmp eax,esi
		je @f
			call buf_flood_fill_recurs_0
		@@:
		inc ebx


		inc ebx
		call get_pixel_24
		cmp eax,esi
		je @f
			call buf_flood_fill_recurs_0
		@@:
		dec ebx

		dec ecx
		call get_pixel_24
		cmp eax,esi
		je @f
			call buf_flood_fill_recurs_0
		@@:
		inc ecx

		inc ecx
		call get_pixel_24
		cmp eax,esi
		je @f
			call buf_flood_fill_recurs_0
		@@:
		dec ecx

	.end_fun:
	ret

;input:
; ebx = coord_x
; ecx = coord_y
; edx = 梥⠧ «¨¢ª¨
; esi = 梥⠯¨ªá¥«¥©, ¯® ª®â®àë¬ ¡ã¤¥â ¨â¨ § «¨¢ª 
; edi = buf_struc
;output:
; eax = ¯®àâ¨âáï
align 4
buf_flood_fill_recurs_1:
	call get_pixel_24
	cmp eax,0xffffffff ;if error coords
	je .end_fun
	cmp eax,edx ;¥á«¨ 梥⠯¨ªá¥«ï ᮢ¯ « á 梥⮬ § «¨¢ª¨, §­ ç¨â § «¨¢ª  ¢ í⮩ ®¡« á⨠㦥 ¡ë«  ᤥ« ­ 
	je .end_fun
	cmp eax,esi ;¥á«¨ 梥⠯¨ªá¥«ï ­¥ ᮢ¯ « á § «¨¢ ¥¬ë¬ 梥⮬ § «¨¢ª¨, â® ¯à¥ªà é ¥¬ § «¨¢ªã
	jne .end_fun

		call draw_pixel

		dec ebx
		call get_pixel_24
		cmp eax,esi
		jne @f
			call buf_flood_fill_recurs_1
		@@:
		inc ebx


		inc ebx
		call get_pixel_24
		cmp eax,esi
		jne @f
			call buf_flood_fill_recurs_1
		@@:
		dec ebx

		dec ecx
		call get_pixel_24
		cmp eax,esi
		jne @f
			call buf_flood_fill_recurs_1
		@@:
		inc ecx

		inc ecx
		call get_pixel_24
		cmp eax,esi
		jne @f
			call buf_flood_fill_recurs_1
		@@:
		dec ecx

	.end_fun:
	ret

;äã­ªæ¨ï ¤«ï à¨á®¢ ­¨ï â®çª¨
align 4
proc buf_set_pixel uses ebx ecx edx edi, buf_struc:dword, coord_x:dword, coord_y:dword, color:dword
	mov edi,dword[buf_struc]
	mov ebx,dword[coord_x]
	mov ecx,dword[coord_y]
	mov edx,dword[color]
	call draw_pixel
	ret
endp

;output:
; eax = 梥â â®çª¨
; ¢ á«ãç ¥ ®è¨¡ª¨ eax = 0xffffffff
align 4
proc buf_get_pixel uses ebx ecx edi, buf_struc:dword, coord_x:dword, coord_y:dword
	mov edi,dword[buf_struc]
	mov ebx,[coord_x]
	mov ecx,[coord_y]

	cmp buf2d_bits,8
	jne @f
		call get_pixel_8
		jmp .end_fun
	@@:
	cmp buf2d_bits,24
	jne @f
		call get_pixel_24
		jmp .end_fun
	@@:
	cmp buf2d_bits,32
	jne @f
		call get_pixel_32
		;jmp .end_fun
	@@:
	.end_fun:
	ret
endp

align 4
proc buf_img_wdiv2, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,8
	jne @f
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		stdcall img_8b_wdiv2, buf2d_data,ecx
	@@:
	cmp buf2d_bits,24
	jne @f
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
	@@:
	cmp buf2d_bits,32
	jne @f
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		stdcall img_rgba32_wdiv2, buf2d_data,ecx
	@@:
	popad
	ret
endp

;input:
;data_8b - pointer to rgb data
;size - count img pixels (size img data / 3(rgb) )
align 4
proc img_8b_wdiv2 data_8b:dword, size:dword
	mov eax,dword[data_8b]
	mov ecx,dword[size] ;ecx = size
	cld
	@@: ;§ â¥¬­¥­¨¥ æ¢¥â  ¯¨ªá¥«¥©
		shr byte[eax],1
		inc eax
		loop @b

	mov eax,dword[data_8b]
	mov ecx,dword[size] ;ecx = size
	shr ecx,1
	@@: ;á«®¦¥­¨¥ 梥⮢ ¯¨ªá¥«¥©
		mov bl,byte[eax+1] ;ª®¯¨à㥬 梥â á®á¥¤­¥£® ¯¨ªá¥«ï
		add byte[eax],bl
		add eax,2
		loop @b

	mov eax,dword[data_8b]
	inc eax
	mov ebx,eax
	inc ebx
	mov ecx,dword[size] ;ecx = size
	shr ecx,1
	dec ecx ;«¨è­¨© ¯¨ªá¥«ì
	@@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
		mov dl,byte[ebx]
		mov byte[eax],dl

		inc eax
		add ebx,2
		loop @b
	ret
endp

;input:
;data_rgb - pointer to rgb data
;size - count img pixels (size img data / 3(rgb) )
align 4
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
  mov eax,dword[data_rgb]
  mov ecx,dword[size] ;ecx = size
  lea ecx,[ecx+ecx*2]
  cld
  @@: ;§ â¥¬­¥­¨¥ æ¢¥â  ¯¨ªá¥«¥©
		shr byte[eax],1
		inc eax
		loop @b

  mov eax,dword[data_rgb]
  mov ecx,dword[size] ;ecx = size
  shr ecx,1
  @@: ;á«®¦¥­¨¥ 梥⮢ ¯¨ªá¥«¥©
		mov bx,word[eax+3] ;ª®¯¨à㥬 梥â á®á¥¤­¥£® ¯¨ªá¥«ï
		add word[eax],bx
		mov bl,byte[eax+5] ;ª®¯¨à㥬 梥â á®á¥¤­¥£® ¯¨ªá¥«ï
		add byte[eax+2],bl
		add eax,6 ;=2*3
		loop @b

  mov eax,dword[data_rgb]
  add eax,3
  mov ebx,eax
  add ebx,3
  mov ecx,dword[size] ;ecx = size
  shr ecx,1
  dec ecx ;«¨è­¨© ¯¨ªá¥«ì
  @@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
		mov edx,dword[ebx]
		mov word[eax],dx
		shr edx,16
		mov byte[eax+2],dl

		add eax,3
		add ebx,6
		loop @b
  ret
endp

;input:
;data_rgba - pointer to rgba data
;size - count img pixels (size img data / 4(rgba) )
align 4
proc img_rgba32_wdiv2 data_rgba:dword, size:dword
	mov eax,dword[data_rgba]

	mov eax,dword[data_rgba]
	mov ebx,eax
	add ebx,4
	mov ecx,dword[size] ;ecx = size
	shr ecx,1
	@@: ;ᬥ訢 ­¨¥ 梥⮢ ¯¨ªá¥«¥©
		call combine_colors_1
		mov [eax],edx
		add eax,8 ;=2*4
		add ebx,8
		loop @b

	mov eax,dword[data_rgba]
	add eax,4
	mov ebx,eax
	add ebx,4
	mov ecx,dword[size] ;ecx = size
	shr ecx,1
	dec ecx ;«¨è­¨© ¯¨ªá¥«ì
	@@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
		mov edx,dword[ebx]
		mov dword[eax],edx

		add eax,4
		add ebx,8
		loop @b
	ret
endp

align 4
proc buf_img_hdiv2, buf_struc:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,8
	jne @f
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		stdcall img_8b_hdiv2, buf2d_data,ecx,eax
	@@:
	cmp buf2d_bits,24
	jne @f
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
	@@:
	cmp buf2d_bits,32
	jne @f
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		shl eax,2
		stdcall img_rgba32_hdiv2, buf2d_data,ecx,eax
	@@:
	popad
	ret
endp

;input:
;data_8b - pointer to 8 bit data
;size - count img pixels (size img data)
;size_w - width img in pixels
align 4
proc img_8b_hdiv2, data_8b:dword, size:dword, size_w:dword

	mov eax,dword[data_8b] ;eax =
	mov ecx,dword[size]
	cld
	@@: ;§ â¥¬­¥­¨¥ æ¢¥â  ¯¨ªá¥«¥©
		shr byte[eax],1
		inc eax
		loop @b

	mov eax,dword[data_8b] ;eax =
	mov esi,dword[size_w]
	mov ebx,esi
	add ebx,eax
	mov ecx,dword[size]  ;ecx = size
	shr ecx,1
	xor edi,edi
	@@: ;á«®¦¥­¨¥ 梥⮢ ¯¨ªá¥«¥©
		mov dl,byte[ebx] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
		add byte[eax],dl

		inc eax
		inc ebx
		inc edi
		cmp edi,dword[size_w]
		jl .old_line
			add eax,esi
			add ebx,esi
			xor edi,edi
		.old_line:
		loop @b


	mov eax,dword[data_8b] ;eax =
	add eax,esi ;esi = width*3(rgb)
	mov ebx,eax
	add ebx,esi
	mov ecx,dword[size] ;ecx = size
	shr ecx,1
	sub ecx,dword[size_w] ;«¨è­ïï áâப  ¯¨ªá¥«¥©
	xor edi,edi
	@@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
		mov dl,byte[ebx] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
		mov byte[eax],dl

		inc eax
		inc ebx
		inc edi
		cmp edi,dword[size_w]
		jl .old_line_2
			add ebx,esi
			xor edi,edi
		.old_line_2:
		loop @b

	ret
endp

;input:
;data_rgb - pointer to rgb data
;size - count img pixels (size img data / 3(rgb) )
;size_w - width img in pixels
align 4
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword

  mov eax,dword[data_rgb] ;eax =
  mov ecx,dword[size]	  ;ecx = size
  lea ecx,[ecx+ecx*2]
  cld
  @@: ;§ â¥¬­¥­¨¥ æ¢¥â  ¯¨ªá¥«¥©
    shr byte[eax],1
    inc eax
    loop @b

  mov eax,dword[data_rgb] ;eax =
  mov esi,dword[size_w]
  lea esi,[esi+esi*2] ;esi = width*3(rgb)
  mov ebx,esi
  add ebx,eax
  mov ecx,dword[size]  ;ecx = size
  shr ecx,1
  xor edi,edi
  @@: ;á«®¦¥­¨¥ 梥⮢ ¯¨ªá¥«¥©
    mov dx,word[ebx] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
    add word[eax],dx
    mov dl,byte[ebx+2] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
    add byte[eax+2],dl

    add eax,3
    add ebx,3
    inc edi
    cmp edi,dword[size_w]
    jl .old_line
      add eax,esi
      add ebx,esi
      xor edi,edi
    .old_line:
    loop @b


  mov eax,dword[data_rgb] ;eax =
  add eax,esi ;esi = width*3(rgb)
  mov ebx,eax
  add ebx,esi
  mov ecx,dword[size] ;ecx = size
  shr ecx,1
  sub ecx,dword[size_w] ;«¨è­ïï áâப  ¯¨ªá¥«¥©
  xor edi,edi
  @@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
    mov edx,dword[ebx] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
    mov word[eax],dx
    shr edx,16
    mov byte[eax+2],dl

    add eax,3
    add ebx,3
    inc edi
    cmp edi,dword[size_w]
    jl .old_line_2
      add ebx,esi
      xor edi,edi
    .old_line_2:
    loop @b

  ret
endp

;input:
;data_rgba - pointer to rgba data
;size - count img pixels (size img data / 4(rgba) )
;size_w_b - width img in bytes
align 4
proc img_rgba32_hdiv2, data_rgba:dword, size:dword, size_w_b:dword

	mov eax,dword[data_rgba] ;eax =
	mov ebx,dword[size_w_b]
	add ebx,eax
	mov ecx,dword[size]  ;ecx = size
	shr ecx,1
	xor edi,edi
	@@: ;ᬥ訢 ­¨¥ 梥⮢ ¯¨ªá¥«¥©
		call combine_colors_1
		mov dword[eax],edx

		add eax,4
		add ebx,4
		add edi,4
		cmp edi,dword[size_w_b]
		jl .old_line
			add eax,dword[size_w_b]
			add ebx,dword[size_w_b]
			xor edi,edi
		.old_line:
		loop @b


	mov eax,dword[data_rgba] ;eax =
	mov ebx,dword[size_w_b]
	add eax,ebx
	add ebx,eax
	mov ecx,dword[size] ;ecx = size
	shl ecx,1
	sub ecx,dword[size_w_b] ;«¨è­ïï áâப  ¯¨ªá¥«¥©
	shr ecx,2
	xor edi,edi
	@@: ;¯®¤¦ â¨¥ ¯¨ªá¥«¥©
		mov edx,dword[ebx] ;ª®¯¨à㥬 梥⠭¨¦­¥£® ¯¨ªá¥«ï
		mov dword[eax],edx

		add eax,4
		add ebx,4
		add edi,4
		cmp edi,dword[size_w_b]
		jl .old_line_2
			add ebx,dword[size_w_b]
			xor edi,edi
		.old_line_2:
		loop @b

	ret
endp

;input:
; eax - 㪠§ â¥«ì ­  32-¡¨â­ë© 梥â
; ebx - 㪠§ â¥«ì ­  32-¡¨â­ë© 梥â
;output:
; edx - 32-¡¨â­ë© 梥â ᬥ蠭­ë© á ãç¥â®¬ ¯à®§à ç­®áâ¨
;destroy:
; esi
align 4
proc combine_colors_1 uses ecx edi
locals
	c_blye dd ?
	c_green dd ?
	c_red dd ?
endl		
	movzx edi,byte[eax+3]
	cmp edi,255
	je .c0z
	movzx esi,byte[ebx+3]
	cmp esi,255
	je .c1z
	cmp edi,esi
	je .c0_c1

	;¯¥à¥¢®à ç¨¢ ¥¬ §­ ç¥­¨ï ¯à®§à ç­®á⥩
	neg edi
	inc edi
	add edi,255
	neg esi
	inc esi
	add esi,255

	movzx ecx,byte[eax]
	imul ecx,edi
	mov [c_blye],ecx
	movzx ecx,byte[ebx]
	imul ecx,esi
	add [c_blye],ecx

	movzx ecx,byte[eax+1]
	imul ecx,edi
	mov [c_green],ecx
	movzx ecx,byte[ebx+1]
	imul ecx,esi
	add [c_green],ecx

	movzx ecx,byte[eax+2]
	imul ecx,edi
	mov [c_red],ecx
	movzx ecx,byte[ebx+2]
	imul ecx,esi
	add [c_red],ecx

push eax ebx
	xor ebx,ebx
	mov eax,[c_red]
	xor edx,edx
	mov ecx,edi
	add ecx,esi
	div ecx
	mov bl,al
	shl ebx,16
	mov eax,[c_green]
	xor edx,edx
	div ecx
	mov bh,al
	mov eax,[c_blye]
	xor edx,edx
	div ecx
	mov bl,al

	shr ecx,1
	;¯¥à¥¢®à ç¨¢ ¥¬ §­ ç¥­¨ï ¯à®§à ç­®áâ¨
	neg ecx
	inc ecx
	add ecx,255

	shl ecx,24
	add ebx,ecx
	mov edx,ebx
pop ebx eax

	jmp .end_f
	.c0_c1: ;¥á«¨ ¯à®§à ç­®á⨠®¡®¨å 梥⮢ ᮢ¯ ¤ îâ
		mov edx,dword[eax]
		shr edx,1
		and edx,011111110111111101111111b
		mov esi,dword[ebx]
		shr esi,1
		and esi,011111110111111101111111b
		add edx,esi
		ror edi,8 ;¯¥à¥¬¥é ¥¬ §­ ç¥­¨¥ ¯à®§à ç­®á⨠¢ áâ à訩 ¡ ©â edi
		or edx,edi
		jmp .end_f
	.c0z: ;¥á«¨ 梥⠢ eax ¯à®§à ç­ë©
		mov edx,dword[ebx]
		movzx edi,byte[ebx+3]
		jmp @f
	.c1z: ;¥á«¨ 梥⠢ ebx ¯à®§à ç­ë©
		mov edx,dword[eax]
	@@:
		add edi,255 ;¤¥« ¥¬ 梥⠭  ¯®«®¢¨­ã ¯à®§à ç­ë¬
		shr edi,1
		cmp edi,255
		jl @f
			mov edi,255 ;¬ ªá¨¬ «ì­ ï ¯à®§à ç­®áâì ­¥ ¡®«¥¥ 255
		@@:
		shl edi,24
		and edx,0xffffff ;á­¨¬ ¥¬ áâ àãî ¯à®§à ç­®áâì
		add edx,edi
	.end_f:
	ret
endp

;¯à¥®¡à §®¢ ­¨¥ ¡ãä¥à  ¨§ 24-¡¨â­®£® ¢ 8-¡¨â­ë©
; spectr - ®¯à¥¤¥«ï¥â ª ª®© ᯥªâà ¡à âì ¯à¨ ¯à¥®¡à §®¢ ­¨¨ 0-ᨭ¨©, 1-§¥«¥­ë©, 2-ªà á­ë©
align 4
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error
		mov eax,buf2d_w
		mov ecx,buf2d_h
		imul ecx,eax
		mov esi,ecx
		;ebx - ¯ ¬ïâì ¨§ ª®â®à®© ª®¯¨àã¥âáï
		;edx - ¯ ¬ïâì ªã¤  ª®¯¨àã¥âáï
		mov edx,buf2d_data
		mov ebx,edx
		cmp [spectr],3
		jge @f
			add ebx,[spectr]
		@@:
			mov al,byte[ebx]
			mov byte[edx],al
			add ebx,3
			inc edx
			loop @b
		mov buf2d_bits,8
		invoke mem.realloc,buf2d_data,esi ;㬥­ìè ¥¬ ¯ ¬ïâì § ­¨¬ ¥¬ãî ¡ãä¥à®¬
		jmp .end_conv
	.error:
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
	.end_conv:
	popad
	ret
endp

;¯à¥®¡à §®¢ ­¨¥ ¡ãä¥à  ¨§ 24-¡¨â­®£® ¢ 32-¡¨â­ë©
align 4
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error1
		mov ecx,buf2d_w
		mov ebx,buf2d_h
		imul ebx,ecx
		mov ecx,ebx ;ecx = size  8 b
		shl ebx,2   ;ebx = size 32 b
		invoke mem.realloc,buf2d_data,ebx ;㢥«¨ç¨¢ ¥¬ ¯ ¬ïâì § ­¨¬ ¥¬ãî ¡ãä¥à®¬
		mov buf2d_data,eax ;­  á«ãç © ¥á«¨ ¨§¬¥­¨«áï 㪠§ â¥«ì ­  ¤ ­­ë¥
		mov buf2d_bits,32
		mov edx,ebx ;edx = size 32 b
		sub ebx,ecx ;ebx = size 24 b
		mov eax,ecx
		;eax - à §¬¥à  8 ¡¨â­ëå ¤ ­­ëå
		;ebx - à §¬¥à 24 ¡¨â­ëå ¤ ­­ëå
		;edx - à §¬¥à 32 ¡¨â­ëå ¤ ­­ëå
		add ebx,buf2d_data
		add edx,buf2d_data
		mov edi,dword[buf_str8]
		cmp buf2d_bits,8
		jne .error2
		add eax,buf2d_data
		mov edi,edx
		;eax - 㪠§ â¥«ì ­  ª®­¥æ  8 ¡¨â­ëå ¤ ­­ëå
		;ebx - 㪠§ â¥«ì ­  ª®­¥æ 24 ¡¨â­ëå ¤ ­­ëå
		;edi - 㪠§ â¥«ì ­  ª®­¥æ 32 ¡¨â­ëå ¤ ­­ëå
		@@:
			sub edi,4 ;®â­¨¬ ¥¬ ¢ ­ ç «¥ 横« ,
			sub ebx,3 ; ¯®â®¬ã, ç⮠㪠§ â¥«¨ áâ®ïâ
			dec eax   ; §  ¯à¥¤¥« ¬¨ ¡ãä¥à®¢
			mov edx,dword[ebx]
			mov dword[edi],edx
			mov dl,byte[eax]
			mov byte[edi+3],dl
			loop @b

		jmp .end_conv
	.error1:
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
		jmp .end_conv
	.error2:
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
	.end_conv:
	popad
	ret
endp

;äã­ªæ¨ï ª®¯¨àã¥â ¨§®¡à ¦¥­¨¥ ¨§ ¡ãä¥à  buf_source (24b|32b) ¢ buf_destination (24b)
; 㪠§ë¢ îâáï ª®®à¤¨­ âë ¢áâ ¢ª¨ ¡ãä¥à  buf_source ®â­®á¨â¥«ì­® buf_destination
; ¯à®§à ç­®áâì ¯à¨ ª®¯¨à®¢ ­¨¨ ­¥ ãç¨â뢠¥âáï
align 4
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
	locals
		right_bytes dd ?
	endl
	pushad

	mov edi,[buf_source]
	cmp buf2d_bits,24
	je .sou24
	cmp buf2d_bits,32
	je .sou32
		jmp .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï

	.sou24: ;¢ ¨áâ®ç­¨ª¥ 24 ¡¨â­ ï ª à⨭ª 
	mov eax,buf2d_w
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov ebx,[coord_x] ;¢ ebx ¢à¥¬¥­­® áâ ¢¨¬ ®âáâ㯠¨§®¡à ¦¥­¨ï (¤«ï ¯à®¢¥àª¨)
	cmp ebx,buf2d_w   ;¯à®¢¥à塞 ¢« §¨â «¨ ¨§®¡à ¦¥­¨¥ ¯® è¨à¨­¥
	jge .copy_end	  ;¥á«¨ ¨§®¡à ¦¥­¨¥ ¯®«­®áâìî ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,0
		jge @f
			;¥á«¨ ª®®à¤¨­ â  coord_y<0 (1-ï ­ áâனª )
			add edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨
			cmp edx,0
			jle .copy_end ;¥á«¨ ª®¯¨à㥬®¥ ¨§®¡à ¦¥­¨¥ ­ å®¤¨âáï ¯®«­®áâìî ­ ¤ ¢¥àå­¥© £à ­¨æ¥© ¡ãä¥à  (coord_y<0 ¨ |coord_y|>buf_source.h)
			neg ecx
			;inc ecx
			imul ecx,eax
			lea ecx,[ecx+ecx*2] ;¯® 3 ¡ ©â  ­  ¯¨ªá¥«ì
			add esi,ecx ;ᤢ¨£ ¥¬ 㪠§ â¥«ì á ª®¯¨à㥬묨 ¤ ­­ë¬¨, á ãç¥â®¬ ¯à®¯ã襭®© ç áâ¨
			xor ecx,ecx ;®¡­ã«ï¥¬ ª®®à¤¨­ âã coord_y
		@@:
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		mov ecx,[coord_y] ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		cmp ecx,0
		jg .end_otr_c_y_24
			;¥á«¨ ª®®à¤¨­ â  coord_y<=0 (2-ï ­ áâனª )
			mov ecx,[coord_x]
			jmp @f
		.end_otr_c_y_24:
		imul ecx,ebx
		add ecx,[coord_x]
		@@:
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data
		sub ebx,eax
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov [right_bytes],0
	mov ecx,[coord_x]
	cmp ecx,ebx
	jl @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		lea ecx,[ecx+ecx*2] ;ecx - ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		mov [right_bytes],ecx
	@@:

	lea eax,[eax+eax*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨
	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨

	cld
	cmp [right_bytes],0
	jg .copy_1
	.copy_0: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		rep movsb
		add edi,ebx
		dec edx
		cmp edx,0
		jg .copy_0
	jmp .copy_end
	.copy_1: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		rep movsb
		add edi,ebx
		add esi,[right_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_1
	jmp .copy_end

	.sou32: ;¢ ¨áâ®ç­¨ª¥ 32 ¡¨â­ ï ª à⨭ª 
	mov eax,buf2d_w
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov ebx,[coord_x] ;¢ ebx ¢à¥¬¥­­® áâ ¢¨¬ ®âáâ㯠¨§®¡à ¦¥­¨ï (¤«ï ¯à®¢¥àª¨)
	cmp ebx,buf2d_w   ;¯à®¢¥à塞 ¢« §¨â «¨ ¨§®¡à ¦¥­¨¥ ¯® è¨à¨­¥
	jge .copy_end	  ;¥á«¨ ¨§®¡à ¦¥­¨¥ ¯®«­®áâìî ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,0
		jge @f
			;¥á«¨ ª®®à¤¨­ â  coord_y<0 (1-ï ­ áâனª )
			add edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨
			cmp edx,0
			jle .copy_end ;¥á«¨ ª®¯¨à㥬®¥ ¨§®¡à ¦¥­¨¥ ­ å®¤¨âáï ¯®«­®áâìî ­ ¤ ¢¥àå­¥© £à ­¨æ¥© ¡ãä¥à  (coord_y<0 ¨ |coord_y|>buf_source.h)
			neg ecx
			;inc ecx
			imul ecx,eax
			shl ecx,2 ;¯® 4 ¡ ©â  ­  ¯¨ªá¥«ì
			add esi,ecx ;ᤢ¨£ ¥¬ 㪠§ â¥«ì á ª®¯¨à㥬묨 ¤ ­­ë¬¨, á ãç¥â®¬ ¯à®¯ã襭®© ç áâ¨
			xor ecx,ecx ;®¡­ã«ï¥¬ ª®®à¤¨­ âã coord_y
		@@:
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		;mov ecx,ebx ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		;imul ecx,[coord_y]
		;add ecx,[coord_x]
		mov ecx,[coord_y] ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		cmp ecx,0
		jg .end_otr_c_y_32
			;¥á«¨ ª®®à¤¨­ â  coord_y<=0 (2-ï ­ áâனª )
			mov ecx,[coord_x]
			jmp @f
		.end_otr_c_y_32:
		imul ecx,ebx
		add ecx,[coord_x]
		@@:
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data
		sub ebx,eax
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov [right_bytes],0
	mov ecx,[coord_x]
	cmp ecx,ebx
	jl @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		shl ecx,2 ;ecx - ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		mov [right_bytes],ecx
	@@:

	;eax - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨
	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨

	cld
	cmp [right_bytes],0
	jg .copy_3
	.copy_2: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		@@:
			movsw
			movsb
			inc esi
			loop @b
		add edi,ebx
		dec edx
		cmp edx,0
		jg .copy_2
	jmp .copy_end
	.copy_3: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		@@:
			movsw
			movsb
			inc esi
			loop @b
		add edi,ebx
		add esi,[right_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_3

	.copy_end:
	popad
	ret
endp

;input:
; esi = pointer to color1 + transparent
; edi = pointer to background color2
;output:
; [edi] = combine color
align 4
combine_colors_0:
	push ax bx cx dx
	mov bx,0x00ff ;---get transparent---
	movzx cx,byte[esi+3] ;pro
	sub bx,cx ;256-pro
	;---blye---
	movzx ax,byte[esi]
	imul ax,bx
	movzx dx,byte[edi]
	imul dx,cx
	add ax,dx
	mov byte[edi],ah
	;---green---
	movzx ax,byte[esi+1]
	imul ax,bx
	movzx dx,byte[edi+1]
	imul dx,cx
	add ax,dx
	mov byte[edi+1],ah
	;---red---
	movzx ax,byte[esi+2]
	imul ax,bx
	movzx dx,byte[edi+2]
	imul dx,cx
	add ax,dx
	mov byte[edi+2],ah

	pop dx cx bx ax
	ret

;äã­ªæ¨ï ª®¯¨àã¥â ¨§®¡à ¦¥­¨¥ ¨§ ¡ãä¥à  buf_source (32b) ¢ buf_destination (24b)
; 㪠§ë¢ îâáï ª®®à¤¨­ âë ¢áâ ¢ª¨ ¡ãä¥à  buf_source ®â­®á¨â¥«ì­® buf_destination
; ¯à¨ ª®¯¨à®¢ ­¨¨ ãç¨â뢠¥âáï ¯à®§à ç­®áâì
align 4
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
	locals
		lost_bytes dd ?
	endl
	pushad

	mov edi,[buf_source]
	cmp buf2d_bits,32
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov eax,buf2d_w
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .copy_end ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,0
		jge @f
			;¥á«¨ ª®®à¤¨­ â  coord_y<0 (1-ï ­ áâனª )
			add edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨
			cmp edx,0
			jle .copy_end ;¥á«¨ ª®¯¨à㥬®¥ ¨§®¡à ¦¥­¨¥ ­ å®¤¨âáï ¯®«­®áâìî ­ ¤ ¢¥àå­¥© £à ­¨æ¥© ¡ãä¥à  (coord_y<0 ¨ |coord_y|>buf_source.h)
			neg ecx
			;inc ecx
			imul ecx,eax
			shl ecx,2 ;¯® 4 ¡ ©â  ­  ¯¨ªá¥«ì
			add esi,ecx ;ᤢ¨£ ¥¬ 㪠§ â¥«ì á ª®¯¨à㥬묨 ¤ ­­ë¬¨, á ãç¥â®¬ ¯à®¯ã襭®© ç áâ¨
			xor ecx,ecx ;®¡­ã«ï¥¬ ª®®à¤¨­ âã coord_y
		@@:
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		mov ecx,ebx ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		cmp [coord_y],0
		jg .end_otr_c_y
			;¥á«¨ ª®®à¤¨­ â  coord_y<=0 (2-ï ­ áâனª )
			mov ecx,[coord_x]
			jmp @f
		.end_otr_c_y:
		imul ecx,[coord_y]
		add ecx,[coord_x]
		@@:
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data
		sub ebx,eax
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov dword[lost_bytes],0
	mov ecx,[coord_x]
	cmp ecx,0
	jge @f
		neg ecx
		;inc ecx
		cmp eax,ecx ;eax - è¨à¨­  ª®¯¨à㥬®© ª à⨭ª¨
		jle .copy_end ;¥á«¨ ª®¯¨à㥬®¥ ¨§®¡à ¦¥­¨¥ ­ å®¤¨âáï ¯®«­®áâìî §  «¥¢®© £à ­¨æ¥© ¡ãä¥à  (coord_x<0 ¨ |coord_x|>buf_source.w)
		shl ecx,2
		mov [lost_bytes],ecx
		add esi,ecx
		shr ecx,2
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		lea ecx,[ecx+ecx*2]
		add edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥
		xor ecx,ecx
	@@:
	cmp ecx,ebx
	jle @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		shl ecx,2 ;ecx - ç¨á«® ¯¨ªá¥«¥© ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		add [lost_bytes],ecx
	@@:

;	mov [right_bytes],0
;	mov ecx,[coord_x]
;	cmp ecx,ebx
;	jl @f
;		sub ecx,ebx
;		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
;		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
;		shl ecx,2 ;ecx - ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
;		mov [right_bytes],ecx
;	@@:

	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨

	cld
	cmp [lost_bytes],0
	jg .copy_1
	.copy_0: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		@@:
			call combine_colors_0
			add edi,3
			add esi,4
			loop @b
		add edi,ebx
		dec edx
		cmp edx,0
		jg .copy_0
	jmp .copy_end
	.copy_1: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		@@:
			call combine_colors_0
			add edi,3
			add esi,4
			loop @b
		add edi,ebx
		add esi,[lost_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_1

	.copy_end:
	popad
	ret
endp

;input:
; ebx - color1
; esi = pointer to transparent
; edi = pointer to background color2
;output:
; [edi] = combine color
align 4
combine_colors_2:
	push ax ebx cx dx si
	mov cl,byte[esi] ;pro
	xor ch,ch
	mov si,0x00ff ;---get transparent---
	sub si,cx ;256-pro

		;---blye---
		movzx ax,bl
		shr ebx,8
		imul ax,si
		movzx dx,byte[edi]
		imul dx,cx
		add ax,dx
		mov byte[edi],ah
		;---green---
		movzx ax,bl
		shr ebx,8
		imul ax,si
		movzx dx,byte[edi+1]
		imul dx,cx
		add ax,dx
		mov byte[edi+1],ah
		;---red---
		movzx ax,bl
		imul ax,si
		movzx dx,byte[edi+2]
		imul dx,cx
		add ax,dx
		mov byte[edi+2],ah

	pop si dx cx ebx ax
	ret

;äã­ªæ¨ï ª®¯¨àã¥â ¨§®¡à ¦¥­¨¥ ¨§ ¡ãä¥à  buf_source (8b) ¢ buf_destination (24b)
; 㪠§ë¢ îâáï ª®®à¤¨­ âë ¢áâ ¢ª¨ ¡ãä¥à  buf_source ®â­®á¨â¥«ì­® buf_destination
align 4
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
	locals
		lost_bytes dd ? ;ç¨á«® ¯®â¥àï­­ëå ¡ ©â®¢ ¢ áâப¥ ª®¯¨à㥬®£® ¨§®¡à ¦¥­ï (â¥å çâ® ­¥ ¢« §ïâ ¢ ¡ãä¥à)
		dest_w_bytes dd ? ;ª®««¨ç¥á⢮ ¡ ©â ¢ ¡ãä¥à¥ ¯à¨¥¬­¨ª¥ ¯® è¨à¨­¥ - è¨à¨­  ¢áâ ¢«ï¥¬®© ª à⨭ª¨
	endl
	pushad

	mov edi,[buf_source]
	cmp buf2d_bits,8
	jne .error1 ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov eax,buf2d_w ;è¨à¨­  ª®¯¨à㥬®© ª à⨭ª¨
	mov edx,buf2d_h ;¢ëá®â  ª®¯¨à㥬®© ª à⨭ª¨
	mov esi,buf2d_data ;¤ ­­ë¥ ª®¯¨à㥬®© ª à⨭ª¨

	mov edi,[buf_destination]
	cmp buf2d_bits,24
	jne .error2 ;ä®à¬ â ¡ãä¥à  ­¥ ¯®®¤¥à¦¨¢ ¥âáï
	mov ebx,[coord_x] ;¢ ebx ¢à¥¬¥­­® áâ ¢¨¬ ®âáâ㯠¨§®¡à ¦¥­¨ï (¤«ï ¯à®¢¥àª¨)
	cmp ebx,buf2d_w   ;¯à®¢¥à塞 ¢« §¨â «¨ ¨§®¡à ¦¥­¨¥ ¯® è¨à¨­¥
	jge .copy_end	  ;¥á«¨ ¨§®¡à ¦¥­¨¥ ¯®«­®áâìî ¢ë« §¨â §  ¯à ¢ãî áâ®à®­ã
		mov ebx,buf2d_h ;ebx - ¢ëá®â  ®á­®¢­®£® ¡ãä¥à 
		mov ecx,[coord_y]
		cmp ecx,0
		jge @f
			;¥á«¨ ª®®à¤¨­ â  coord_y<0 (1-ï ­ áâனª )
			add edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨
			cmp edx,0
			jle .copy_end ;¥á«¨ ª®¯¨à㥬®¥ ¨§®¡à ¦¥­¨¥ ­ å®¤¨âáï ¯®«­®áâìî ­ ¤ ¢¥àå­¥© £à ­¨æ¥© ¡ãä¥à  (coord_y<0 ¨ |coord_y|>buf_source.h)
			neg ecx
			;inc ecx
			imul ecx,eax
			add esi,ecx ;ᤢ¨£ ¥¬ 㪠§ â¥«ì á ª®¯¨à㥬묨 ¤ ­­ë¬¨, á ãç¥â®¬ ¯à®¯ã襭®© ç áâ¨
			xor ecx,ecx ;®¡­ã«ï¥¬ ª®®à¤¨­ âã coord_y
		@@:
		cmp ecx,ebx
		jge .copy_end ;¥á«¨ ª®®à¤¨­ â  'y' ¡®«ìè¥ ¢ëá®âë ¡ãä¥à 
		add ecx,edx ;ecx - ­¨¦­ïï ª®®à¤¨­ â  ª®¯¨à㥬®© ª à⨭ª¨
		cmp ecx,ebx
		jle @f
			sub ecx,ebx
			sub edx,ecx ;㬥­ìè ¥¬ ¢ëá®âã ª®¯¨à㥬®© ª à⨭ª¨, ¢ á«ãç¥ ª®£¤  ®­  ¢ë« §¨â §  ­¨¦­îî £à ­¨æã
		@@:
		mov ebx,buf2d_w
		mov ecx,[coord_y] ;ecx ¨á¯®«ì§ã¥¬ ¤«ï ¢à¥¬¥­­ëå 楫¥©
		cmp ecx,0
		jg .end_otr_c_y
			;¥á«¨ ª®®à¤¨­ â  coord_y<=0 (2-ï ­ áâனª )
			mov ecx,[coord_x]
			jmp @f
		.end_otr_c_y:
		imul ecx,ebx
		add ecx,[coord_x]
		@@:
		lea ecx,[ecx+ecx*2]
		add ecx,buf2d_data ;buf2d_data ¤ ­­ë¥ ®á­®¢­®£® ¡ãä¥à 
		sub ebx,eax ;ebx - è¨à¨­  ®á­®¢­®£® ¡ãä¥à  ¬¨­ãá è¨à¨­  à¨á㥬®£® ¡ãä¥à 
		mov edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥

	mov dword[lost_bytes],0
	mov ecx,[coord_x]
	cmp ecx,0
	jge @f
		neg ecx
		;inc ecx
		cmp eax,ecx ;eax - è¨à¨­  ª®¯¨à㥬®© ª à⨭ª¨
		jle .copy_end ;¥á«¨ ª®¯¨à㥬®¥ ¨§®¡à ¦¥­¨¥ ­ å®¤¨âáï ¯®«­®áâìî §  «¥¢®© £à ­¨æ¥© ¡ãä¥à  (coord_x<0 ¨ |coord_x|>buf_source.w)
		mov [lost_bytes],ecx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		add esi,ecx
		lea ecx,[ecx+ecx*2]
		add edi,ecx ;edi 㪠§ â¥«ì ­  ¤ ­­ë¥ ¡ãä¥à , ªã¤  ¡ã¤¥â ¯à®¨§¢®¤¨âáï ª®¯¨à®¢ ­¨¥
		xor ecx,ecx
	@@:
	cmp ecx,ebx
	jle @f
		sub ecx,ebx
		sub eax,ecx ;㪮à ç¨¢ ¥¬ ª®¯¨à㥬ãî áâபã
		add ebx,ecx ;㤫¨­­ï¥¬ áâப㠤«ï ᤢ¨£  £« ¢­®© ª à⨭ª¨ ¡ãä¥à 
		;ecx - ç¨á«® ¯¨ªá¥«¥© ¢ 1-© áâப¥ ª à⨭ª¨, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî áâ®à®­ã
		add [lost_bytes],ecx
	@@:

	lea ebx,[ebx+ebx*2] ;ª®««¨ç¥á⢮ ¡ ©â ¢ 1-© áâப¥ ¡ãä¥à  ¬¨­ãá ç¨á«® ¡ ©â ¢ 1-© áâப¥ ª®¯¨à㥬®© ª à⨭ª¨
	mov [dest_w_bytes],ebx
	mov ebx,[color]

	cld
	cmp dword[lost_bytes],0
	jg .copy_1
	.copy_0: ;¯à®á⮥ ª®¯¨à®¢ ­¨¥
		mov ecx,eax
		@@:
			call combine_colors_2
			add edi,3
			inc esi
			loop @b
		add edi,[dest_w_bytes]
		dec edx
		cmp edx,0
		jg .copy_0
	jmp .copy_end
	.copy_1: ;­¥ ¯à®á⮥ ª®¯¨à®¢ ­¨¥ (ª à⨭ª  ¢ë« §¨â §  «¥¢ãî ¨/¨«¨ ¯à ¢ãî áâ®à®­ã)
		mov ecx,eax
		@@:
			call combine_colors_2
			add edi,3
			inc esi
			loop @b
		add edi,[dest_w_bytes]
		add esi,[lost_bytes] ;¤®¡ ¢«ï¥¬ ¡ ©âë, ª®â®àë¥ ¢ë« §ïâ §  ¯à ¢ãî £à ­¨æã
		dec edx
		cmp edx,0
		jg .copy_1

	jmp .copy_end
	.error1:
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
		jmp .copy_end
	.error2:
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
	.copy_end:
	popad
	ret
endp

;¯à¥®¡à §®¢ ­¨¥ 8-¡¨â­®£® ¡ãä¥à  à §¬¥à®¬ 16*16 ¢ à §¬¥à 1*256 ᨬ¢®«®¢
align 4
proc buf_convert_text_matrix, buf_struc:dword
	locals
		tmp_mem dd ?
		c1 dw ?
		c2 dd ?
		c3 dw ?
	endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,8
	jne .error
		mov ecx,buf2d_h
		mov ebx,ecx
		shr ebx,4 ;¯à¥¤¯®« £ ¥¬ çâ® ¢ ¡ãä¥à¥ 16 áâப á ᨬ¢®« ¬¨, ¯®â®¬ã ¤¥«¨¬ ­  2^4
		mov edx,buf2d_w
		imul ecx,edx ;ecx = size  8 b
		invoke mem.alloc,ecx ;¢ë¤¥«ï¥¬ ¢à¥¬¥­­ãî ¯ ¬ïâì
		mov [tmp_mem],eax ;eax - new memory

		shr edx,4 ;¯à¥¤¯®« £ ¥¬ çâ® ¢ ¡ãä¥à¥ 16 ª®«®­®ª á ᨬ¢®« ¬¨, ¯®â®¬ã ¤¥«¨¬ ­  2^4
		mov eax,ebx
		imul ebx,edx ;¢ëç¨á«ï¥¬ ª®®«¨ç¥á⢮ ¯¨ªá¥«¥© ­  1 ᨬ¢®«
		;eax = bhe - ¢ëá®â  ¡ãª¢ë
		;ebx = bwi*bhe - ª®««¨ç¥á⢮ ¯¨ªá¥«¥© ¢ 1-© ¡ãª¢¥
		;edx = bwi - è¨à¨­  ¡ãª¢ë
		;ecx,esi,edi - ¨á¯®«ì§ãîâáï ¢ 横«¥ .c_0
		shr buf2d_w,4
		shl buf2d_h,4 ;¯à¥®¡à §®¢ë¢ ¥¬ à §¬¥àë ¡ãä¥à 

		cld
		mov esi,buf2d_data
		mov edi,[tmp_mem]
		mov word[c3],16
		.c_3:
			mov dword[c2],eax
			.c_2:
				mov word[c1],16
				.c_1:
					mov ecx,edx ;.c_0:
					rep movsb
					add edi,ebx
					sub edi,edx ;edi+=(bwi*bhe-bwi)
					dec word[c1]
					cmp word[c1],0
					jg .c_1
				add edi,edx
				shl ebx,4
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
				shr ebx,4
				dec dword[c2]
				cmp dword[c2],0
				jg .c_2
			sub edi,ebx
			shl ebx,4
			add edi,ebx ;edi+=(15*bwi*bhe)
			shr ebx,4
			dec word[c3]
			cmp word[c3],0
			jg .c_3

		mov edi,dword[buf_struc] ;ª®¯¨à®¢ ­¨¥ ­®¢®© ¬ âà¨æë ¢ ®á­®¢­®© ¡ãä¥à
		mov edi,buf2d_data
		mov esi,[tmp_mem]
		mov ecx,ebx
		shl ecx,8
		rep movsb
		invoke mem.free,[tmp_mem] ;ç¨á⨬ ¢à¥¬¥­­ãî ¯ ¬ïâì
		jmp .end_conv
	.error:
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
	.end_conv:
	popad
	ret
endp

align 4
buf_s_matr buf_2d_header ? ;«®ª «ì­ ï ¬ âà¨æ  ᨬ¢®« 

align 4
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
	locals
		buf_t_matr_offs dd ?
	endl
	pushad
	mov edi,dword[buf_struc]
	cmp buf2d_bits,24
	jne .error2
	mov edi,dword[buf_t_matr]
	cmp buf2d_bits,8
	jne .error1
		mov edx,buf2d_data
		mov [buf_t_matr_offs],edx
		mov ecx,BUF_STRUCT_SIZE ;ª®¯¨à㥬 áâàãªâãàã ⥪á⮢®© ¬ âà¨æë
		mov esi,edi
		lea edi,[buf_s_matr]
		cld
		rep movsb
		lea edi,[buf_s_matr]
		shr buf2d_h,8 ;¤¥«¨¬ ¢ëá®âã ᨬ¢®«ì­®£® ¡ãä¥à  ­  256, ¤«ï ­ å®¦¤¥­¨ï ¢ëá®âë 1-£® ᨬ¢®« 
		mov ebx,buf2d_h ;¡¥à¥¬ ¢ëá®âã ᨬ¢®« 
		mov ecx,buf2d_w ;¡¥à¥¬ è¨à¨­ã ᨬ¢®« 

		mov eax,[coord_x]
		mov esi,[text]
		cmp byte[esi],0
		je .end_draw ;¥á«¨ ¯ãáâ ï áâப 
		@@:
			xor edx,edx
			mov dl,byte[esi] ;¡¥à¥¬ ª®¤ ᨬ¢®« 
			imul edx,ebx ;㬭®¦ ¥¬ ¥£® ­  ¢ëá®âã ᨬ¢®« 
			imul edx,ecx ;㬭®¦ ¥¬ ­  è¨à¨­ã ᨬ¢®« 
			add edx,[buf_t_matr_offs] ;¯à¨¡ ¢«ï¥¬ ᬥ饭¨¥ 0-£® ᨬ¢®« , â. ¥. ¯®«ãç ¥âáï ᬥ饭¨¥ ¢ë¢®¤¨¬®£® ᨬ¢®« 
			mov buf2d_data,edx ;¢ «®ª «ì­ë© ¡ãä¥à ᨬ¢®« , áâ ¢¨¬ 㪠§ â¥«ì ­  ­ã¦­ë© ᨬ¢®« ¨§ ¡ãä¥à  buf_t_matr
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
			add eax,ecx
			.new_s:
				inc esi
				cmp byte[esi],13
				jne .no_13
					mov eax,[coord_x]
					add [coord_y],ebx
					jmp .new_s
				.no_13:
			cmp byte[esi],0
			jne @b
		jmp .end_draw
	.error1:
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
		jmp .end_draw
	.error2:
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
	.end_draw:
	popad
	ret
endp

align 4
proc print_err, fun:dword, mes:dword ;¢ë¢®¤¨¬ á®®¡é¥­¨¥ ®¡ 訡ª¥ ­  ¤®áªã ®â« ¤ª¨
	pushad
	mov eax,63
	mov ebx,1

	mov esi,[fun]
	@@:
		mov cl,byte[esi]
		int 0x40
		inc esi
		cmp byte[esi],0
		jne @b
	mov cl,':'
	int 0x40
	mov cl,' '
	int 0x40
	mov esi,[mes]
	@@:
		mov cl,byte[esi]
		int 0x40
		inc esi
		cmp byte[esi],0
		jne @b
	popad
	ret
endp

;input:
; ebp+8  = p0
; ebp+12 = p1
align 4
line_len4i:
	push ebp
	mov ebp,esp
		finit
		fild word [ebp+8]
		fisub word [ebp+12]
		fmul st0,st0 ;st0=x^2
		fild word [ebp+10]
		fisub word [ebp+14]
		fmul st0,st0 ;st0=y^2
		fadd st0,st1
		fsqrt
		fstp dword [ebp+12]
	pop ebp
	ret 4 ;8

align 4
proc buf_curve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
	locals
		delt_t dd ?
		opr_param dd ?
		v_poi_0 dd ?
	endl
	pushad

;float t, xt,yt;
;for(t=.0;t<1.;t+=.005){
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
;  dc.SetPixel(xt,yt,255L);
;}

	mov edx,[color] ;set curve color
	mov edi,[buffer]
	xor ebx,ebx
	xor ecx,ecx

	finit

	; calculate delta t
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
	fadd dword[esp]
	add esp,4 ;pop ...

	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
	fadd dword[esp]
	add esp,4 ;pop ...

	fadd st0,st0 ; len*=2
	ftst
	fstsw ax

	fld1
	sahf
	jle @f ;¨§¡¥£ ¥¬ ¤¥«¥­¨ï ­  0
		fdiv st0,st1
	@@:
	fstp dword[delt_t]

	finit

	;fild word[coord_p2+2] ;y2
	fild word[coord_p1+2] ;y1
	fild word[coord_p0+2] ;y0
	fild word[coord_p2] ;x2
	fild word[coord_p1] ;x1
	fild word[coord_p0] ;x0
	fld dword[delt_t]
	fldz ;t=.0

	@@:
		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st0 ;pow(1.-t,2)
		fmul st0,st3 ;...*x0
		fstp dword[opr_param]

		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st1 ;(1.-t)*t
		fadd st0,st0
		fmul st0,st4 ;...*x1
		mov esi,dword[opr_param]
		fstp dword[opr_param]

		fldz
		fadd st0,st1 ;0+t
		fmul st0,st0 ;t*t
		fmul st0,st5 ;...*x2

		fadd dword[opr_param]
		mov dword[opr_param],esi
		fadd dword[opr_param]
		fistp word[v_poi_0] ;x

		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st0 ;pow(1.-t,2)
		fmul st0,st6 ;...*y0
		fstp dword[opr_param]

		fld1
		fsub st0,st1 ;1.-t
		fmul st0,st1 ;(1.-t)*t
		fadd st0,st0
		fmul st0,st7 ;...*y1
		mov esi,dword[opr_param]
		fstp dword[opr_param]

		fldz
		fadd st0,st1 ;0+t
		fmul st0,st0 ;t*t
		fimul word[coord_p2+2] ;...*y2

		fadd dword[opr_param]
		mov dword[opr_param],esi
		fadd dword[opr_param]
		fistp word[v_poi_0+2] ;y

		mov eax,1
		mov bx,word[v_poi_0+2]
		mov cx,word[v_poi_0]
		call draw_pixel

		fadd st0,st1 ;t+dt

		fld1
		fcomp
		fstsw ax
		sahf
	jae @b

	popad
	ret
endp



;*** ä㭪樨 ¤«ï à ¡®âë á ¢®ªá¥«ì­®© £à ä¨ª®© ***



;ᮧ¤ ­¨¥ ¢®ªá¥«ì­ëå ª¨á⥩
align 4
proc vox_brush_create uses eax ebx ecx edi, h_br:dword, buf_z:dword
	mov edi,[h_br]
	movzx ecx,byte[edi+3]
	add edi,4

	; *** ᮧ¤ ­¨¥ ¥¤¨­¨ç­®© ª¨á⨠***
	mov eax,[buf_z]
	mov buf2d_data,eax
	movzx eax,byte[edi-4] ;è¨à¨­  ¥¤¨­¨ç­®© ª¨áâ¨
	mov buf2d_w,eax ;è¨à¨­  ¡ãä¥à 
	movzx eax,byte[edi-4+1] ;¢ëá®â  ¥¤¨­¨ç­®© ª¨áâ¨
	mov buf2d_h,eax ;¢ëá®â  ¡ãä¥à 
	mov buf2d_size_lt,0 ;®âáâ㯠᫥¢  ¨ á¯à ¢  ¤«ï ¡ãä¥à 
	mov buf2d_color,0 ;梥â ä®­  ¡ãä¥à 
	mov buf2d_bits,32 ;ª®«¨ç¥á⢮ ¡¨â ¢ 1-© â®çª¥ ¨§®¡à ¦¥­¨ï

	; *** ᮧ¤ ­¨¥ á«¥¤ãîé¨å ª¨á⥩ ***
	cmp ecx,1
	jl .end_creat
	movzx ebx,byte[edi-4+2] ;¢ëá®â  ®á­®¢ ­¨ï ¥¤¨­¨ç­®© ª¨áâ¨
	shr ebx,1
	cld
	@@:
		mov eax,edi
		add edi,BUF_STRUCT_SIZE
		stdcall vox_create_next_brush, eax, edi, ebx
		shl ebx,1
		loop @b
	.end_creat:
	ret
endp

;㤠«¥­¨¥ ¢®ªá¥«ì­ëå ª¨á⥩
align 4
proc vox_brush_delete uses ecx edi, h_br:dword
	mov edi,[h_br]
	movzx ecx,byte[edi+3]
	add edi,4

	; *** 㤠«¥­¨¥ ª¨á⥩ ***
	cmp ecx,1
	jl .end_delete
	cld
	@@:
		add edi,BUF_STRUCT_SIZE
		stdcall buf_delete, edi
		loop @b
	.end_delete:
	ret
endp

;äã­ªæ¨ï ¤«ï ᮧ¤ ­¨ï ¢®ªá¥«ï á«¥¤ãî饣® ¯®à浪 
; buf_v1 - ¡ãä¥à á ¨á室­ë¬ ¢®ªá¥«¥¬
; buf_v2 - ¡ãä¥à á 㢥«¨ç¥­ë¬ ¢®ªá¥«¥¬
; h - ¢ëá®â  ®á­®¢ ­¨ï ¨á室­®£® ¢®ªá¥«ï : 2
align 4
proc vox_create_next_brush uses eax ebx ecx edx edi, buf_v1:dword, buf_v2:dword, h:dword
	mov edi,[buf_v1]
	mov ebx,buf2d_h
	mov ecx,buf2d_w
	mov edi,[buf_v2]
	mov buf2d_h,ebx
	shl buf2d_h,1
	mov buf2d_w,ecx
	shl buf2d_w,1
	mov buf2d_color,0
	mov buf2d_bits,32

	stdcall buf_create, [buf_v2] ;ᮧ¤ ­¨¥ ¡ãä¥à  £«ã¡¨­ë
	shr ecx,1
	mov edx,[h]
	shl edx,1
	sub ebx,edx
	;ecx - è¨à¨­  ¨á室­®£® ¢®ªá¥«ï : 2
	;ebx - ¢ëá®â  ¨á室­®£® ¢®ªá¥«ï (¡¥§ ®á­®¢ ­¨ï)
	;edx - ¢ëá®â  ®á­®¢ ­¨ï ¨á室­®£® ¢®ªá¥«ï
	mov eax,[h]
	cmp eax,0
	je @f
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,0
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,0

		stdcall vox_add, [buf_v2], [buf_v1], 0,eax,eax
		push eax ;stdcall ...
		add eax,ebx
		stdcall vox_add, [buf_v2], [buf_v1], 0,eax ;,...
		sub eax,ebx
		shl ecx,1

		;ecx - è¨à¨­  ¨á室­®£® ¢®ªá¥«ï
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax,eax
		push eax ;stdcall ...,[h]
		add eax,ebx
		stdcall vox_add, [buf_v2], [buf_v1], ecx,eax;,[h]
		;sub eax,ebx
		shr ecx,1

		;ecx - è¨à¨­  ¨á室­®£® ¢®ªá¥«ï : 2
		stdcall vox_add, [buf_v2], [buf_v1], ecx,edx,edx
		add ebx,edx
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,edx

		jmp .end_0
	@@:
		;¥á«¨ h = 0, ⮣¤  ¯®«ãç ¥¬ ª¨áâì ­  2 £à ­¨
		;¢ â ª®¬ á«ãç ¥ ¤«ï ¯®«ã祭¨ï £«ã¡¨­ë ¡¥à¥¬ è¨à¨­ã / 2
		mov eax,ecx
		;2 «¥¢ëå ¢®ªá¥«ï
		stdcall vox_add, [buf_v2], [buf_v1], 0,0,eax
		stdcall vox_add, [buf_v2], [buf_v1], 0,ebx,eax
		shl eax,1
		;2 業âà «ì­ëå ¯¥à¥¤­¨å ¢®ªá¥«ï (§ ¤­¨¥ 業âà «ì­ë¥ ­¥ ¢ë¢®¤¨¬)
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax
		shr eax,1
		shl ecx,1
		;2 ¯à ¢ëå ¢®ªá¥«ï
		stdcall vox_add, [buf_v2], [buf_v1], ecx,0,eax
		stdcall vox_add, [buf_v2], [buf_v1], ecx,ebx,eax

	.end_0:


	ret
endp

;
align 4
proc vox_add, buf_v1:dword, buf_v2:dword, coord_x:dword, coord_y:dword, coord_z:dword
pushad
	mov ebx,[coord_x]
	mov eax,[coord_y]
	mov edi,[buf_v2]
	mov ecx,buf2d_h
	mov esi,buf2d_w
	imul ecx,esi
	add esi,ebx
	mov edx,buf2d_data
	cld
	;ecx - count pixels in voxel
	;edx - 㪠§ â¥«ì ­  ¤ ­­ë¥ ¢ ¢®ªá¥«ì­®¬ ¡ãä¥à¥
	;edi - 㪠§ â¥«ì ­  ¢®ªá¥«ì­ë© ¡ãä¥à
	;esi - width voxel buffer add coord x
	.cycle:
		cmp dword[edx],0
		je @f
			;¯à®¢¥à塞 ¡ãä¥à £«ã¡¨­ë
			push eax ecx edi esi
			mov ecx,eax
			mov edi,[buf_v1]
			call get_pixel_32 ;stdcall buf_get_pixel, [buf_v1],ebx,ecx
			mov esi,[edx]
			add esi,[coord_z]
			cmp eax,esi
			jge .end_draw
			stdcall buf_set_pixel, [buf_v1],ebx,ecx,esi ;esi = new coord z
			.end_draw:
			pop esi edi ecx eax
		@@:
		add edx,4
		inc ebx
		cmp ebx,esi
		jl @f
			inc eax
			sub ebx,buf2d_w
		@@:
		loop .cycle
popad
	ret
endp

;description:
; ¢®§¢à è ¥â è¨à¨­ã ¢®ªá¥«ì­®£® ¨§®¡à ¦¥­¨ï á 3-¬ï £à ­ï¬¨
; ¯à¨­¨¬ ¥â 㪠§ â¥«ì ­  ª¨áâì ¨ ¬ áèâ ¡
align 4
proc buf_vox_obj_get_img_w_3g uses ecx, h_br:dword,k_scale:dword
	mov ecx,[h_br]

	movzx eax,byte[ecx]
	cmp dword[k_scale],1
	jl .end_c0
		mov ecx,[k_scale]
		shl eax,cl
	.end_c0:
	ret
endp

;description:
; ¢®§¢à è ¥â ¢ëá®âã ¢®ªá¥«ì­®£® ¨§®¡à ¦¥­¨ï á 3-¬ï £à ­ï¬¨
; ¯à¨­¨¬ ¥â 㪠§ â¥«ì ­  ª¨áâì ¨ ¬ áèâ ¡
align 4
proc buf_vox_obj_get_img_h_3g uses ecx, h_br:dword,k_scale:dword
	mov ecx,[h_br]

	movzx eax,byte[ecx+1]
	cmp dword[k_scale],1
	jl .end_c0
		mov ecx,[k_scale]
		shl eax,cl
	.end_c0:
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï ¢®ªá¥«ì­ë© ®¡ê¥ªâ (¢¨¤­  1 £à ­ì)
;input:
; buf_i - ¡ãä¥à ¢ ª®â®à®¬ à¨áã¥âáï (24 ¡¨â )
; buf_z - ¡ãä¥à £«ã¡¨­ë (32 ¡¨â  ¯® ç¨á«ã ¯¨ªá¥«¥© ¤®«¦¥­ ᮢ¯ ¤ âì á buf_i)
align 4
proc buf_vox_obj_draw_1g, buf_i:dword, buf_z:dword, v_obj:dword, coord_x:dword,\
coord_y:dword, k_scale:dword
	cmp [k_scale],0
	jl .end_f
pushad
	mov edi,[buf_i]
	cmp buf2d_bits,24
	jne .error1
	mov edi,[buf_z]
	cmp buf2d_bits,32
	jne .error2

	mov ecx,[k_scale]
	mov ebx,[coord_x]
	mov edx,[coord_y]
	mov edi,[v_obj]
	add edi,vox_offs_data
	xor esi,esi
	stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]

	jmp .end_0
	.error1:
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n24b
		jmp .end_0
	.error2:
		stdcall print_err,sz_buf2d_vox_obj_draw_1g,txt_err_n32b
	.end_0:
popad
	.end_f:
	ret
endp

;input:
; ebx - coord_x
; edx - coord_y
; esi - coord_z
; ecx - ã஢¥­ì ⥪ã襣® 㧫 
; edi - 㪠§ â¥«ì ­  ¤ ­­ë¥ ¢®ªá¥«ì­®£® ®¡ê¥ªâ 
align 4
proc draw_sub_vox_obj_1g, buf_i:dword, buf_z:dword, v_obj:dword
	cmp byte[edi+3],0 ;ᬮâਬ ¥áâì «¨ ¯®¤¤¥à¥¢ìï
	je .sub_trees

		;¯à®à¨á®¢ª  à ¬ª¨ ¥á«¨ à §¬¥à 㧫  = 1
		cmp ecx,0
		jne @f
			;¯à®¢¥àª  £«ã¡¨­ë esi
			stdcall buf_get_pixel, [buf_z], ebx,edx, esi
			cmp eax,esi
			jge @f
				push ecx
				mov ecx,dword[edi]
				and ecx,0xffffff
				stdcall buf_set_pixel, [buf_i], ebx,edx, ecx
				stdcall buf_set_pixel, [buf_z], ebx,edx, esi
				pop ecx
		@@:

		;४ãàᨢ­ë© ¯¥à¥¡®à ¯®¤¤¥à¥¢ì¥¢
		push edx
		;¢å®¤ ¢­ãâàì 㧫 
		dec ecx

		mov eax,1
		cmp ecx,1
		jl @f
			shl eax,cl
		@@:

		add edx,eax ;ª®à¥ªâ¨à®¢ª  ¢ëá®âë ¯®¤ ¢®ªá¥«ì ­¨¦­¥£® ã஢­ï

		mov ah,byte[edi+3]
		add edi,4
		mov al,8
		.cycle:
			bt ax,8 ;â¥áâ¨à㥬 ⮫쪮 ah
			jnc .c_next
				push eax ebx edx esi
				stdcall vox_corect_coords_pl, [v_obj],1
				stdcall draw_sub_vox_obj_1g, [buf_i],[buf_z],[v_obj]
				pop esi edx ebx eax
			.c_next:
			shr ah,1
			dec al
			jnz .cycle
		;¢ë室 ¨§ 㧫 
		inc ecx
		pop edx
		jmp .end_f
	.sub_trees:
		cmp ecx,0
		jl .end_0 ;­¥ à¨á㥬 ®ç¥­ì ¬ «¥­ìª¨¥ ¢®ªá¥«¨

			;à¨á㥬 㧥«
			mov eax,[edi]
			and eax,0xffffff
			
			cmp ecx,1
			jl @f
				;ª¢ ¤à â ¡®«ìè¥ â¥ªã饣® ¬ áèâ ¡ 
				stdcall vox_draw_square_1g, [buf_i],[buf_z],eax
				jmp .end_0
			@@:
				;ª¢ ¤à â ⥪ã饣® ¬ áèâ ¡ 
				push ecx
				mov ecx,eax
				stdcall buf_get_pixel, [buf_z], ebx,edx
				cmp eax,esi
				jge .end_1
				stdcall buf_set_pixel, [buf_i], ebx,edx,ecx
				stdcall buf_set_pixel, [buf_z], ebx,edx,esi
				.end_1:
				pop ecx
		.end_0:
		add edi,4
	.end_f:
	ret
endp

;output:
; eax - à §àãè ¥âáï
align 4
proc vox_draw_square_1g uses ecx edx edi, buf_i:dword, buf_z:dword, color:dword
locals
	img_size dd ?
	coord_y dd ?
endl
	mov edi,[buf_z]
	xor eax,eax
	inc eax
	shl eax,cl
	mov [img_size],eax
	mov [coord_y],eax
	.cycle_0:
	push ebx
	mov ecx,[img_size]
	cld
	.cycle_1:
		push ecx
		mov ecx,edx
		call get_pixel_32
		pop ecx
		cmp eax,esi
		jge @f
			stdcall buf_set_pixel, [buf_i], ebx,edx, [color]
			stdcall buf_set_pixel, edi, ebx,edx, esi
		@@:
		inc ebx
	loop .cycle_1
	pop ebx
	inc edx
	dec dword[coord_y]
	jnz .cycle_0
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï ¢®ªá¥«ì­ë© ®¡ê¥ªâ (¢¨¤­® 3 £à ­¨)
;input:
; buf_i - ¡ãä¥à ¢ ª®â®à®¬ à¨áã¥âáï (24 ¡¨â )
; buf_z - ¡ãä¥à £«ã¡¨­ë (32 ¡¨â  ¯® ç¨á«ã ¯¨ªá¥«¥© ¤®«¦¥­ ᮢ¯ ¤ âì á buf_i)
; h_br - ª¨áâì á ¨§®¡à ¦¥­¨ï¬¨ ¢®ªá¥«¥© (32 ¡¨â )
; v_obj - ¢®ªá¥«ì­ë© ®¡ê¥ªâ
; k_scale - ª®íä. ¤«ï ¬ áèâ ¡¨à®¢ ­¨ï ¨§®¡à ¦¥­¨ï
align 4
proc buf_vox_obj_draw_3g, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword
pushad
	mov edi,[v_obj]
	mov ecx,[k_scale]
	mov ebx,[coord_x]
	mov edx,[coord_y]
	add edi,vox_offs_data
	mov esi,[coord_z]
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
popad
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï ç áâì ¢®ªá¥«ì­®£® ®¡ê¥ªâ 
;input:
; buf_i - ¡ãä¥à ¢ ª®â®à®¬ à¨áã¥âáï (24 ¡¨â )
; buf_z - ¡ãä¥à £«ã¡¨­ë (32 ¡¨â  ¯® ç¨á«ã ¯¨ªá¥«¥© ¤®«¦¥­ ᮢ¯ ¤ âì á buf_i)
; h_br - ª¨áâì á ¨§®¡à ¦¥­¨ï¬¨ ¢®ªá¥«¥© (32 ¡¨â )
; v_obj - ¢®ªá¥«ì­ë© ®¡ê¥ªâ
; k_scale - ª®íä. ¤«ï ¬ áèâ ¡¨à®¢ ­¨ï ¨§®¡à ¦¥­¨ï
align 4
proc buf_vox_obj_draw_3g_scaled, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword,\
coord_x:dword, coord_y:dword, coord_z:dword, k_scale:dword,\
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword,b_color:dword
pushad
locals
	p_node dd 0 ;த¨â¥«ì᪨© 㧥«
endl
	mov edi,[v_obj]
	add edi,vox_offs_data

	mov ecx,[k_scale]
	mov ebx,[coord_x]

	;â¥á⮢ ï à ¬ª 
	mov eax,[h_br]

	movzx edx,byte[eax]
	movzx esi,byte[eax+1]
	cmp ecx,1
	jl .end_c0
		shl edx,cl
		shl esi,cl
	.end_c0:
	;stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]

	;¢¥à⨪ «ì­ ï ¯®«®á 
	add ebx,edx
	shr edx,cl
	stdcall buf_rect_by_size, [buf_i], ebx,[coord_y],edx,esi, [b_color]
	mov ecx,[s_k_scale]
	shr esi,cl
	xor eax,eax
	inc eax
	shl eax,cl
	dec eax
	sub eax,[s_c_z] ;§­ ç¥­¨ï ¯® ®á¨ z ¢®§à áâ îâ á ­¨§ã ¢¢¥àå
	imul eax,esi
	add eax,[coord_y]
	stdcall buf_filled_rect_by_size, [buf_i], ebx,eax,edx,esi, [b_color]
	mov ebx,[coord_y]
	shl esi,cl
	add ebx,esi
	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
	shr eax,1
	mov esi,[h_br]
	movzx esi,byte[esi+1]
	;¯®«§ã­®ª
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,eax,esi, [s_c_x], [s_k_scale], [b_color]
	mov edx,[coord_x]
	add edx,eax
	;¯®«§ã­®ª
	stdcall draw_polz_hor, [buf_i], edx,ebx,eax,esi, [s_c_y], [s_k_scale], [b_color]
;---

	mov esi,[s_k_scale]
	cmp esi,1
	jl .end_2

	; *** (1) ***
	.found:
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
	movzx bx,byte[edi+3]
	mov [p_node],edi
	add edi,4
	cmp eax,0
	je .end_1
	mov ecx,eax
	cld
	@@: ;横« ¤«ï ¯à®¯ã᪠ ¯à¥¤ë¤ãé¨å ¯®¤¤¥à¥¢ì¥¢ ¢ 㧫¥
		bt bx,0 ;¯à®¢¥à塞 ¥áâì «¨ ¤®ç¥à­¨¥ 㧫ë
		jnc .end_0
			xor eax,eax
			stdcall vox_obj_rec0 ;¢ eax ¢ëç¨á«ï¥âáï ç¨á«® ¤®ç¥à­¨å 㧫®¢, ¢ ¤ ­­®© ¢¥â¢¨
		.end_0:
		shr bx,1
		loop @b
	.end_1:
	bt bx,0
	jnc .end_2 ;¥á«¨ ¯®¤¤¥à¥¢  ­¥ áãé¥áâ¢ã¥â
	dec esi
	cmp esi,0
	jg .found

	; *** (2) ***
	;à¨á®¢ ­¨¥ ç á⨠®¡ê¥ªâ 
	mov ecx,[k_scale]
	mov ebx,[coord_x]
	mov edx,[coord_y]
	mov esi,[coord_z]
	stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
	.end_2:

popad
	ret
endp

;input:
; h_br - ª¨áâì á ¨§®¡à ¦¥­¨ï¬¨ ¢®ªá¥«¥© (32 ¡¨â )
; ebx - coord_x
; edx - coord_y
; esi - coord_z
; ecx - ã஢¥­ì ⥪ã襣® 㧫 
; edi - 㪠§ â¥«ì ­  ¤ ­­ë¥ ¢®ªá¥«ì­®£® ®¡ê¥ªâ 
align 4
proc vox_go_in_node, buf_i:dword, buf_z:dword, h_br:dword, v_obj:dword
	cmp byte[edi+3],0 ;ᬮâਬ ¥áâì «¨ ¯®¤¤¥à¥¢ìï
	je .sub_trees
		;४ãàᨢ­ë© ¯¥à¥¡®à ¯®¤¤¥à¥¢ì¥¢
		push eax edx

		;¯à®à¨á®¢ª  à ¬ª¨ ¥á«¨ à §¬¥à 㧫  = 1
		cmp ecx,0
		jne .end_2
			push eax
				stdcall vox_get_sub_brush,[h_br],0 ;®¯à¥¤¥«ï¥¬ ª¨áâì ¤«ï à¨á®¢ ­¨ï
				cmp eax,0 ;¥á«¨ ª¨áâì ­¥ ­ ©¤¥­ 
				je @f
					stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
				@@:
			pop eax
		.end_2:

		;¢å®¤ ¢­ãâàì 㧫 
		dec ecx
;---
		push ebx
			;mov eax,(h-h_osn/2)
			mov ebx,[h_br]
			movzx eax,byte[ebx+1]
			cmp byte[ebx+2],0
			je @f
				;¥á«¨ ª¨áâì á 3-¬ï £à ­ï¬¨
				movzx ebx,byte[ebx+2]
				shr ebx,1
				sub eax,ebx
				jmp .end_0
			@@:
				;¥á«¨ ª¨áâì á 2-¬ï £à ­ï¬¨
				movzx ebx,byte[ebx]
				shr ebx,1
			.end_0:
		cmp ecx,1
		jl @f
			shl eax,cl
			shl ebx,cl
		@@:
		add esi,ebx
		pop ebx
		add edx,eax ;ª®à¥ªâ¨à®¢ª  ¢ëá®âë ¯®¤ ¢®ªá¥«ì ­¨¦­¥£® ã஢­ï
;---
		mov ah,byte[edi+3]
		add edi,4
		mov al,8
		.cycle:
			bt ax,8 ;â¥áâ¨à㥬 ⮫쪮 ah
			jnc .c_next
				push ebx edx esi
				stdcall vox_corect_coords, [h_br], [v_obj]
				stdcall vox_go_in_node, [buf_i], [buf_z], [h_br], [v_obj]
				pop esi edx ebx
			.c_next:
			shr ah,1
			dec al
			jnz .cycle

		;¢ë室 ¨§ 㧫 
		inc ecx
		pop edx eax

		jmp .end_f
	.sub_trees:
		;à¨á㥬 㧥«
		push eax
			stdcall vox_get_sub_brush,[h_br],ecx ;®¯à¥¤¥«ï¥¬ ª¨áâì ¤«ï à¨á®¢ ­¨ï
			cmp eax,0 ;¥á«¨ ª¨áâì ­¥ ­ ©¤¥­ 
			je @f
				stdcall draw_vox, [buf_i], [buf_z], eax, ebx,edx,esi, [edi]
			@@:
		pop eax

		add edi,4
	.end_f:
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï ®¤¨­®ç­ë© ¢®ªá¥«
;input:
; buf_i - ¡ãä¥à ¢ ª®â®à®¬ à¨áã¥âáï (24 ¡¨â )
; buf_z - ¡ãä¥à £«ã¡¨­ë (32 ¡¨â  ¯® ç¨á«ã ¯¨ªá¥«¥© ¤®«¦¥­ ᮢ¯ ¤ âì á buf_i)
; buf_v - ¡ãä¥à á ¨§®¡à ¦¥­¨¥¬ ¢®ªá¥«ï (32 ¡¨â )
; v_color - 梥â
align 4
proc draw_vox, buf_i:dword, buf_z:dword, buf_v:dword,\
coord_x:dword, coord_y:dword, coord_z:dword, v_color:dword
pushad
	mov eax,[coord_x]
	mov ebx,[coord_y]
	mov edi,[buf_v]
	mov ecx,buf2d_h
	mov esi,buf2d_w
	imul ecx,esi
	add esi,eax
	mov edx,buf2d_data
	cld
	;ecx - count pixels in voxel
	;edx - 㪠§ â¥«ì ­  ¤ ­­ë¥ ¢ ¢®ªá¥«ì­®¬ ¡ãä¥à¥
	;edi - 㪠§ â¥«ì ­  ¢®ªá¥«ì­ë© ¡ãä¥à
	;esi - width voxel buffer add coord x
	.cycle:
		cmp dword[edx],0
		je @f
			;¯à®¢¥à塞 ¡ãä¥à £«ã¡¨­ë
			push eax
			stdcall buf_get_pixel, [buf_z],eax,ebx
			sub eax,[coord_z]
			cmp eax,[edx]
			jl .dr_pixel
				pop eax
				jmp @f
			.dr_pixel:
				;à¨á㥬 â®çªã
				pop eax
				stdcall buf_set_pixel, [buf_i],eax,ebx,[v_color]
				push ecx
				mov ecx,[coord_z]
				add ecx,[edx]
				stdcall buf_set_pixel, [buf_z],eax,ebx,ecx
				pop ecx
		@@:
		add edx,4
		inc eax
		cmp eax,esi
		jl @f
			inc ebx
			sub eax,buf2d_w
		@@:
		loop .cycle
popad
	ret
endp

;description:
;äã­ªæ¨ï ¤«ï ª®à¥ªâ¨à®¢ª¨ ª®®à¤¨­ â
;­ ¯à ¢«¥­¨ï ®á¥© ª®®à¤¨­ â ¢ ¢®ªá¥«¥:
;*z
;|
;+
;  * y
; /
;+
; \
;  * x
;input:
;  al - ­®¬¥à 㧫  ¢ ¤¥à¥¢¥ (®â 1 ¤® 8)
; ebx - ª®®à¤¨­ â  x
; edx - ª®®à¤¨­ â  y
; esi - ª®®à¤¨­ â  z
; ecx - ã஢¥­ì ⥪ã襣® 㧫 
;output:
; ebx - ­®¢ ï ª®®à¤¨­ â  x
; edx - ­®¢ ï ª®®à¤¨­ â  y
; esi - ­®¢ ï ª®®à¤¨­ â  z
align 4
proc vox_corect_coords, h_br:dword, v_obj:dword
locals
	osn_w_2 dd ? ;è¨à¨­  ®á­®¢ ­¨ï ¥¤¨­¨ç­®£® ¢®ªá¥«ï : 2
	vox_h dd ? ;¢ëá®â  ¥¤¨­¨ç­®£® ¢®ªá¥«ï
endl
	cmp ecx,0
	jl .end_f ;¤«ï ã᪮७¨ï ®âà¨á®¢ª¨

	push eax edi
	and eax,15 ;¢ë¤¥«ï¥¬ ­®¬¥à 㧫  ¢ ¤¥à¥¢¥
	mov edi,[v_obj]
	add edi,vox_offs_tree_table
	add edi,8
	sub edi,eax

	push ebx ecx
		mov ebx,[h_br]

		movzx ecx,byte[ebx]
		shr ecx,1
		mov dword[osn_w_2],ecx

		movzx ecx,byte[ebx+2]
		movzx ebx,byte[ebx+1]
		sub ebx,ecx
		mov dword[vox_h],ebx
		shr ecx,1
		mov eax,ecx ;eax - ¢ëá®â  ®á­®¢ ­¨ï ¥¤¨­¨ç­®£® ¢®ªá¥«ï : 2
	pop ecx ebx

	cmp ecx,1
	jl @f ;¢® ¨§¡¥¦ ­¨¥ § æ¨ª«¨¢ ­¨ï
		shl eax,cl
		shl dword[osn_w_2],cl
		shl dword[vox_h],cl
	@@:

;	add esi,eax ;¬¥­ï¥¬ £«ã¡¨­ã ¤«ï ¡ãä¥à  z (ª®¬¯¥­á æ¨ï ¤«ï ª®®à¤¨­ âë y)
	bt word[edi],0 ;test voxel coord x
	jnc @f
		add ebx,[osn_w_2]
		cmp eax,0
		jne .end_0
			add esi,[osn_w_2] ;¬¥­ï¥¬ £«ã¡¨­ã ¤«ï ¡ãä¥à  z
			jmp @f
		.end_0:
		add edx,eax
		add esi,eax ;¬¥­ï¥¬ £«ã¡¨­ã ¤«ï ¡ãä¥à  z
	@@:
	bt word[edi],1 ;test voxel coord y
	jnc @f
		add ebx,[osn_w_2]
		cmp eax,0
		jne .end_1
			sub esi,[osn_w_2] ;¬¥­ï¥¬ £«ã¡¨­ã ¤«ï ¡ãä¥à  z
			jmp @f
		.end_1:
		sub edx,eax
		sub esi,eax ;¬¥­ï¥¬ £«ã¡¨­ã ¤«ï ¡ãä¥à  z
	@@:
	bt word[edi],2 ;test voxel coord z
	jnc @f
		sub edx,[vox_h]
	@@:
	pop edi eax
	.end_f:
	ret
endp

;¨§¢«¥ª ¥¬ ¨§ h_br 㪠§ â¥«ì ­  ¡ãä¥à á ¨§®¡à ¦¥­¨¥¬ ¢®ªá¥«ï, 㪠§ ­­®£® ¯®à浪  n
align 4
proc vox_get_sub_brush uses ebx ecx, h_br:dword, n:dword
	xor eax,eax
	mov ebx,[n]
	cmp ebx,0
	jl @f
	mov ecx,[h_br]
	cmp bl,byte[ecx+3]
	jg @f
		add ecx,4
		imul ebx,BUF_STRUCT_SIZE
		mov eax,ebx
		add eax,ecx
	@@:
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï á१ ¢®ªá¥«ì­®£® ®¡ì¥ªâ 
;input:
; v_size - à §¬¥à ª¢ ¤à â  á ¢®ªá¥«¥¬
; k_scale - á⥯¥­ì ¤¥â «¨§ æ¨¨ ¨§®¡à ¦¥­¨ï
; n_plane - ­®¬¥à ¯«®áª®á⨠á¥ç­¨ï (¢ ¯à¥¤¥« å ®â 0 ¤® 2^k_scale - 1)
; b_color - 梥⠣࠭¨æë
align 4
proc buf_vox_obj_draw_pl, buf_i:dword, v_obj:dword, coord_x:dword,\
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword
	cmp [k_scale],0
	jl .end_f
pushad
	mov eax,[v_size]
	mov ecx,[k_scale]
	mov ebx,eax
	cmp ecx,1
	jl @f
		shl ebx,cl
	@@:
	;ebx - ¯®«­ë© à §¬¥à ¨§®¡à ¦¥­¨ï
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;à ¬ª  ­  à¨áã­®ª
	mov edx,ebx
	add ebx,[coord_y]
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;¯®«§ã­®ª, ¯®ª §ë¢ î騩 ­®¬¥à á¥ç¥­¨ï

	;à¨á®¢ ­¨¥ â®ç¥ª ¤«ï á¥âª¨
	push ecx
	mov edi,1
	cmp ecx,1
	jl @f
		shl edi,cl
	@@:
	dec edi
	cmp edi,1
	jl .end_0
	mov ecx,edi
	imul ecx,edi
	mov ebx,[coord_x]
	mov edx,[coord_y]
	add edx,eax
	xor esi,esi
	cld
	@@:
		add ebx,eax
		inc esi
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
		cmp esi,edi
		jl .end_1
			;¯¥à¥å®¤ â®ç¥ª ­  ­®¢ãî áâபã
			xor esi,esi
			mov ebx,[coord_x]
			add edx,eax
		.end_1:
		loop @b
	.end_0:
	pop ecx

	;eax - à §¬¥à ®¤­®£® ª¢ ¤à â 
	;edi - 㪠§ â¥«ì ­  à¨áã¥¬ë¥ ¤ ­­ë¥ ¨§ ®¡ê¥ªâ 
	mov ebx,[coord_x]
	mov edx,[coord_y]
	mov edi,[v_obj]
	add edi,vox_offs_data
	xor esi,esi
	push eax
	mov eax,1
	shl eax,cl
	dec eax
	sub eax,[n_plane]
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],eax
popad
	.end_f:
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï á१ ç á⨠¢®ªá¥«ì­®£® ®¡ì¥ªâ 
;input:
; s_c_x, s_c_y, s_c_z, s_k_scale - ¯ à ¬¥âàë ®¯à¥¤¥«ïî騥 ç áâì ¢®ªá¥«ì­®£® ®¡ê¥ªâ , ª®â®à ï ¡ã¤¥â à¨á®¢ âìáï
align 4
proc buf_vox_obj_draw_pl_scaled, buf_i:dword, v_obj:dword, coord_x:dword,\
coord_y:dword, v_size:dword, k_scale:dword, n_plane:dword, b_color:dword,\
s_c_x:dword, s_c_y:dword, s_c_z:dword, s_k_scale:dword
	cmp [k_scale],0
	jl .end_f
pushad
locals
	p_node dd 0 ;த¨â¥«ì᪨© 㧥«
endl
	mov eax,[v_size]
	mov ecx,[k_scale]
	mov ebx,eax
	cmp ecx,1
	jl @f
		shl ebx,cl
	@@:
	;ebx - ¯®«­ë© à §¬¥à ¨§®¡à ¦¥­¨ï
	stdcall buf_rect_by_size, [buf_i], [coord_x],[coord_y],ebx,ebx, [b_color] ;à ¬ª  ­  à¨áã­®ª
	mov edx,ebx
	add ebx,[coord_y]
	stdcall draw_polz_hor, [buf_i], [coord_x],ebx,edx,eax, [n_plane], [k_scale], [b_color] ;¯®«§ã­®ª, ¯®ª §ë¢ î騩 ­®¬¥à á¥ç¥­¨ï

	;à¨á®¢ ­¨¥ â®ç¥ª ¤«ï á¥âª¨
	push ecx
	mov edi,1
	cmp ecx,1
	jl @f
		shl edi,cl
	@@:
	dec edi
	cmp edi,1
	jl .end_3
	mov ecx,edi
	imul ecx,edi
	mov ebx,[coord_x]
	mov edx,[coord_y]
	add edx,eax
	xor esi,esi
	cld
	@@:
		add ebx,eax
		inc esi
		stdcall buf_set_pixel, [buf_i], ebx,edx, [b_color]
		cmp esi,edi
		jl .end_4
			;¯¥à¥å®¤ â®ç¥ª ­  ­®¢ãî áâபã
			xor esi,esi
			mov ebx,[coord_x]
			add edx,eax
		.end_4:
		loop @b
	.end_3:
	pop ecx

	mov esi,[s_k_scale]
	cmp esi,1
	jl .end_2
	mov edi,[v_obj]
	add edi,vox_offs_data

	; *** (1) ***
	.found:
	stdcall vox_obj_get_node_position, [v_obj],[s_c_x],[s_c_y],[s_c_z],esi
	movzx bx,byte[edi+3]
	mov [p_node],edi
	add edi,4
	cmp eax,0
	je .end_1
	mov ecx,eax
	cld
	@@: ;横« ¤«ï ¯à®¯ã᪠ ¯à¥¤ë¤ãé¨å ¯®¤¤¥à¥¢ì¥¢ ¢ 㧫¥
		bt bx,0 ;¯à®¢¥à塞 ¥áâì «¨ ¤®ç¥à­¨¥ 㧫ë
		jnc .end_0
			xor eax,eax
			stdcall vox_obj_rec0 ;¢ eax ¢ëç¨á«ï¥âáï ç¨á«® ¤®ç¥à­¨å 㧫®¢, ¢ ¤ ­­®© ¢¥â¢¨
		.end_0:
		shr bx,1
		loop @b
	.end_1:
	bt bx,0
	jnc .end_2 ;¥á«¨ ¯®¤¤¥à¥¢  ­¥ áãé¥áâ¢ã¥â
	dec esi
	cmp esi,0
	jg .found

	mov eax,[v_size]
	;eax - à §¬¥à ®¤­®£® ª¢ ¤à â 
	;edi - 㪠§ â¥«ì ­  à¨áã¥¬ë¥ ¤ ­­ë¥ ¨§ ®¡ê¥ªâ 
	mov ecx,[k_scale]
	mov ebx,[coord_x]
	mov edx,[coord_y]
	xor esi,esi
	push eax
	mov eax,1
	shl eax,cl
	dec eax
	sub eax,[n_plane]
	stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj], eax

	.end_2:
popad
	.end_f:
	ret
endp

;description:
; ®¯à¥¤¥«¥­¨¥ ¯®§¨æ¨¨ 㧫  ¢ ¤¥à¥¢¥ (®â 0 ¤® 7)
align 4
proc vox_obj_get_node_position uses ebx ecx edi, v_obj:dword,\
coord_x:dword,coord_y:dword,coord_z:dword,k_scale:dword
	mov ecx,[k_scale]
	dec ecx
	mov eax,[coord_x]
	mov ebx,[coord_y]
	mov edi,[coord_z]
	cmp ecx,1
	jl .end_0
		shr eax,cl
		shr ebx,cl
		shr edi,cl
	.end_0:
	and eax,1
	bt ebx,0
	jnc @f
		bts eax,1
	@@:
	bt edi,0
	jnc @f
		bts eax,2
	@@:

	mov edi,[v_obj]
	add edi,vox_offs_tree_table
	@@:
		cmp al,byte[edi]
		je @f
		inc edi
		jmp @b
	@@:
	sub edi,[v_obj]
	sub edi,vox_offs_tree_table
	mov eax,edi
	
	ret
endp

;input:
; edi - 㪠§ â¥«ì ­  ¤ ­­ë¥ ¢®ªá¥«ì­®£® ®¡ê¥ªâ 
;output:
; eax - eax + ç¨á«® 㧫®¢ ¢ ¤ ­­ëå ¢®ªá. ®¡ê¥ªâ 
; edi - 㪠§ â¥«ì ­  ᬥ饭­ë¥ ¤ ­­ë¥ ¢®ªá. ®¡ê¥ªâ 
align 4
proc vox_obj_rec0
	inc eax
	cmp byte[edi+3],0 ;ᬮâਬ ¥áâì «¨ ¯®¤¤¥à¥¢ìï
	je .sub_trees

		;४ãàᨢ­ë© ¯¥à¥¡®à ¯®¤¤¥à¥¢ì¥¢
		push ebx ecx
		mov bh,byte[edi+3]
		add edi,4
		mov bl,8
		.cycle:
			bt bx,8 ;â¥áâ¨à㥬 ⮫쪮 bh
			jnc .c_next
				stdcall vox_obj_rec0
			.c_next:
			shr bh,1
			dec bl
			jnz .cycle
		pop ecx ebx

		jmp .end_f
	.sub_trees:
		add edi,4
	.end_f:
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï £®à¨§®­â «ì­ãî ¯®«®áã á ¯®«§ã­ª®¬
align 4
proc draw_polz_hor uses eax ebx ecx, buf:dword, coord_x:dword, coord_y:dword,\
size_x:dword, size_y:dword, pos:dword, k_scale:dword, color:dword
	mov ebx,[size_x]
	stdcall buf_rect_by_size, [buf], [coord_x],[coord_y],ebx,[size_y], [color]
	mov ecx,[k_scale]
	shr ebx,cl
	mov eax,[pos]
	imul eax,ebx
	add eax,[coord_x]
	stdcall buf_filled_rect_by_size, [buf], eax,[coord_y],ebx,[size_y], [color]
	ret
endp

;input:
; ebx - coord_x
; edx - coord_y
; esi - coord_z
; ecx - ã஢¥­ì ⥪ã襣® 㧫 
; edi - 㪠§ â¥«ì ­  ¤ ­­ë¥ ¢®ªá¥«ì­®£® ®¡ê¥ªâ 
align 4
proc draw_sub_vox_obj_pl, buf_i:dword, v_obj:dword, clip_z:dword,\
v_size:dword
	cmp byte[edi+3],0 ;ᬮâਬ ¥áâì «¨ ¯®¤¤¥à¥¢ìï
	je .sub_trees

		;¯à®à¨á®¢ª  à ¬ª¨ ¥á«¨ à §¬¥à 㧫  = 1
		cmp ecx,0
		jne @f
			;¯à®¢¥àª  £«ã¡¨­ë esi
			;clip_z=n_plane
			stdcall vox_is_clip, [clip_z];,[v_size]
			cmp eax,0
			je @f
				push ecx
				mov ecx,dword[edi]
				and ecx,0xffffff
				stdcall buf_rect_by_size, [buf_i], ebx,edx, [v_size],[v_size],ecx
				pop ecx
		@@:

		;४ãàᨢ­ë© ¯¥à¥¡®à ¯®¤¤¥à¥¢ì¥¢
		push edx
		;¢å®¤ ¢­ãâàì 㧫 
		dec ecx

		mov eax,[v_size]
		cmp ecx,1
		jl @f
			shl eax,cl
		@@:

		add edx,eax ;ª®à¥ªâ¨à®¢ª  ¢ëá®âë ¯®¤ ¢®ªá¥«ì ­¨¦­¥£® ã஢­ï

		mov ah,byte[edi+3]
		add edi,4
		mov al,8
		.cycle:
			bt ax,8 ;â¥áâ¨à㥬 ⮫쪮 ah
			jnc .c_next
				push eax ebx edx esi
				stdcall vox_corect_coords_pl, [v_obj],[v_size]
				stdcall draw_sub_vox_obj_pl, [buf_i],[v_obj],[clip_z],[v_size]
				pop esi edx ebx eax
			.c_next:
			shr ah,1
			dec al
			jnz .cycle
		;¢ë室 ¨§ 㧫 
		inc ecx
		pop edx
		jmp .end_f
	.sub_trees:
		cmp ecx,0
		jl .end_0 ;­¥ à¨á㥬 ®ç¥­ì ¬ «¥­ìª¨¥ ¢®ªá¥«¨

			;¯à®¢¥àª  £«ã¡¨­ë esi
			;clip_z=n_plane
			stdcall vox_is_clip, [clip_z]
			cmp eax,0
			je .end_0

			;à¨á㥬 㧥«
			mov eax,[edi]
			and eax,0xffffff
			push eax ;梥â 㧫 

			mov eax,[v_size]
			cmp ecx,1
			jl @f
				;ª¢ ¤à â ¡®«ìè¥ â¥ªã饣® ¬ áèâ ¡ 
				shl eax,cl ;à §¬¥à 㧫 
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
				push ebx edx esi
				mov esi,eax
				inc ebx
				inc edx
				sub esi,2
				mov eax,[buf_i]
				push dword 128
				push dword[eax+16] ;+16 - b_color
				stdcall combine_colors_3,[edi]
				stdcall buf_rect_by_size, [buf_i], ebx,edx, esi,esi,eax
				pop esi edx ebx
				jmp .end_0
			@@:
				;ª¢ ¤à â ⥪ã饣® ¬ áèâ ¡ 
				stdcall buf_filled_rect_by_size, [buf_i], ebx,edx, eax,eax
		.end_0:
		add edi,4
	.end_f:
	ret
endp

;description:
; ¢á¯®¬®£ â¥«ì­ ï äã­ªæ¨ï ¤«ï ¯à®¢¥àª¨ £«ã¡¨­ë esi
;input:
; ecx - ã஢¥­ì ⥪ã襣® 㧫 
; esi - coord z
; clip_z - n_plane
;output:
; eax - 0 if no draw, 1 if draw
align 4
proc vox_is_clip uses ebx edi, clip_z:dword
	xor eax,eax
	mov ebx,[clip_z]
	mov edi,1
	cmp ecx,1
	jl @f
		shl edi,cl
	@@:
	;edi = 2^ecx
	add edi,esi
	cmp edi,ebx ;if (esi+2^ecx <= n_plane) no draw
	jle @f
	inc ebx
	cmp esi,ebx ;if (esi >= (n_plane+1)) no draw
	jge @f
		inc eax
	@@:
	ret
endp

;äã­ªæ¨ï ¤«ï ª®à¥ªâ¨à®¢ª¨ ª®®à¤¨­ â
;­ ¯à ¢«¥­¨ï ®á¥© ª®®à¤¨­ â ¢ ¢®ªá¥«¥:
;*z
;|
;+-* x
;input:
;  al - ­®¬¥à 㧫  ¢ ¤¥à¥¢¥ (®â 1 ¤® 8)
; ebx - ª®®à¤¨­ â  x
; edx - ª®®à¤¨­ â  y
; esi - ª®®à¤¨­ â  z
; ecx - ã஢¥­ì ⥪ã襣® 㧫 
;output:
; ebx - ­®¢ ï ª®®à¤¨­ â  x
; edx - ­®¢ ï ª®®à¤¨­ â  y
; esi - ­®¢ ï ª®®à¤¨­ â  z
align 4
proc vox_corect_coords_pl, v_obj:dword, v_size:dword
	cmp ecx,0
	jl .end_f ;¤«ï ã᪮७¨ï ®âà¨á®¢ª¨

	push eax edi
	and eax,15 ;¢ë¤¥«ï¥¬ ­®¬¥à 㧫  ¢ ¤¥à¥¢¥
	mov edi,[v_obj]
	add edi,vox_offs_tree_table
	add edi,8
	sub edi,eax

	mov eax,[v_size]
	cmp ecx,1
	jl @f
		shl eax,cl
	@@:

	bt word[edi],0 ;test voxel coord x
	jnc @f
		add ebx,eax
	@@:
	bt word[edi],2 ;test voxel coord z
	jnc @f
		sub edx,eax
	@@:
	bt word[edi],1 ;test voxel coord y
	jc @f
		mov eax,1
		cmp ecx,1
		jl .end_0
			shl eax,cl
		.end_0:
		add esi,eax ;¬¥­ï¥¬ £«ã¡¨­ã ¤«ï ¡ãä¥à  z
	@@:
	pop edi eax
	.end_f:
	ret
endp

;description:
; äã­ªæ¨ï à¨áãîé ï ⥭¨
;input:
; buf_i - ¡ãä¥à ¢ ª®â®à®¬ à¨áã¥âáï (24 ¡¨â )
; buf_z - ¡ãä¥à £«ã¡¨­ë (32 ¡¨â  ¯® ç¨á«ã ¯¨ªá¥«¥© ¤®«¦¥­ ᮢ¯ ¤ âì á buf_i)
; h_br - ª¨áâì á ¨§®¡à ¦¥­¨ï¬¨ ¢®ªá¥«¥© (32 ¡¨â )
; k_scale - ª®íä. ¤«ï ¬ áèâ ¡¨à®¢ ­¨ï ¨§®¡à ¦¥­¨ï
align 4
proc buf_vox_obj_draw_3g_shadows, buf_i:dword, buf_z:dword, h_br:dword, \
coord_x:dword, coord_y:dword, color:dword, k_scale:dword, prop:dword
locals
	correct_z dd 0 ;ª®à¥ªâ¨à®¢ª  ¤«ï ¡ãä¥à  £«ã¡¨­ë
endl
pushad
	mov eax,[k_scale]
	add eax,[prop]
	mov dword[correct_z],8
	sub [correct_z],eax
	mov ebx,[coord_x]
	;correct_z = 8-k_scale-prop

	stdcall buf_vox_obj_get_img_w_3g, [h_br],[k_scale]
	mov edx,eax ;edx - è¨à¨­  ¨§®¡à ¦¥­¨ï
	stdcall buf_vox_obj_get_img_h_3g, [h_br],[k_scale]
	mov esi,eax

	mov edi,[coord_y]
	mov ecx,edx
	add edx,ebx ;è¨à¨­  + ®âáâ㯠᫥¢ 
	imul ecx,esi
	cld
	.cycle_0:
		stdcall buf_get_pixel, [buf_z],ebx,edi
		cmp eax,0
		je @f
			stdcall vox_correct_z, [correct_z]
			push eax
			stdcall buf_get_pixel, [buf_i],ebx,edi
			stdcall combine_colors_3,eax,[color] ;,eax
			stdcall buf_set_pixel, [buf_i],ebx,edi,eax
		@@:
		inc ebx
		cmp ebx,edx
		jl @f
			mov ebx,[coord_x]
			inc edi
		@@:
		loop .cycle_0

popad
	ret
endp

;output:
; eax - scaled coord z
align 4
proc vox_correct_z uses ecx, correct_z:dword
	mov ecx,[correct_z]
	cmp ecx,0
	je .end_f
	jl .end_0
		shl eax,cl
		jmp .end_f
	.end_0:
		neg ecx
		inc ecx
		shr eax,cl
	.end_f:
	ret
endp

;output:
; eax - color
align 4
proc combine_colors_3 uses ebx ecx edx edi esi, col_0:dword, col_1:dword, alpha:dword

	mov ebx,[col_0]
	mov ecx,[col_1]
	movzx di,byte[alpha] ;pro
	mov si,0x00ff ;---get transparent---
	sub si,di ;256-pro

	;---blye---
	movzx ax,bl
	imul ax,si
	movzx dx,cl
	imul dx,di
	add ax,dx
	mov cl,ah
	;---green---
	movzx ax,bh
	imul ax,si
	movzx dx,ch
	imul dx,di
	add ax,dx
	mov ch,ah
	shr ebx,16
	ror ecx,16
	;---red---
	movzx ax,bl
	imul ax,si
	movzx dx,cl
	imul dx,di
	add ax,dx

	shl eax,8
	ror ecx,16
	mov ax,cx
	and eax,0xffffff

	ret
endp

txt_err_n8b db 'need buffer 8 bit',13,10,0
txt_err_n24b db 'need buffer 24 bit',13,10,0
txt_err_n32b db 'need buffer 32 bit',13,10,0
txt_err_n8_24b db 'need buffer 8 or 24 bit',13,10,0

align 16
EXPORTS:
	dd sz_lib_init, lib_init
	dd sz_buf2d_create, buf_create
	dd sz_buf2d_create_f_img, buf_create_f_img
	dd sz_buf2d_clear, buf_clear
	dd sz_buf2d_draw, buf_draw_buf
	dd sz_buf2d_delete, buf_delete
	dd sz_buf2d_resize, buf_resize
	dd sz_buf2d_rotate, buf_rotate
	dd sz_buf2d_line, buf_line_brs
	dd sz_buf2d_line_sm, buf_line_brs_sm
	dd sz_buf2d_rect_by_size, buf_rect_by_size
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
	dd sz_buf2d_circle, buf_circle
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
	dd sz_buf2d_bit_blt, buf_bit_blt
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
	dd sz_buf2d_curve_bezier, buf_curve_bezier
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
	dd sz_buf2d_draw_text, buf_draw_text
	dd sz_buf2d_crop_color, buf_crop_color
	dd sz_buf2d_offset_h, buf_offset_h
	dd sz_buf2d_flood_fill, buf_flood_fill
	dd sz_buf2d_set_pixel, buf_set_pixel
	dd sz_buf2d_get_pixel, buf_get_pixel
	dd sz_buf2d_vox_brush_create, vox_brush_create
	dd sz_buf2d_vox_brush_delete, vox_brush_delete
	dd sz_buf2d_vox_obj_get_img_w_3g, buf_vox_obj_get_img_w_3g
	dd sz_buf2d_vox_obj_get_img_h_3g, buf_vox_obj_get_img_h_3g
	dd sz_buf2d_vox_obj_draw_1g, buf_vox_obj_draw_1g
	dd sz_buf2d_vox_obj_draw_3g, buf_vox_obj_draw_3g
	dd sz_buf2d_vox_obj_draw_3g_scaled, buf_vox_obj_draw_3g_scaled
	dd sz_buf2d_vox_obj_draw_pl, buf_vox_obj_draw_pl
	dd sz_buf2d_vox_obj_draw_pl_scaled, buf_vox_obj_draw_pl_scaled
	dd sz_buf2d_vox_obj_draw_3g_shadows, buf_vox_obj_draw_3g_shadows
	dd 0,0
	sz_lib_init db 'lib_init',0
	sz_buf2d_create db 'buf2d_create',0
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
	sz_buf2d_clear db 'buf2d_clear',0 ;®ç¨á⪠ ¡ãä¥à  㪠§ ­­ë¬ 梥⮬
	sz_buf2d_draw db 'buf2d_draw',0
	sz_buf2d_delete db 'buf2d_delete',0
	sz_buf2d_resize db 'buf2d_resize',0
	sz_buf2d_rotate db 'buf2d_rotate',0
	sz_buf2d_line db 'buf2d_line',0 ;à¨á®¢ ­¨¥ «¨­¨¨
	sz_buf2d_line_sm db 'buf2d_line_sm',0 ;à¨á®¢ ­¨¥ ᣫ ¦¥­­®© «¨­¨¨
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;à¨á®¢ ­¨¥ à ¬ª¨ ¯àאַ㣮«ì­¨ª , 2-ï ª®®à¤¨­ â  § ¤ ­  ¯® à §¬¥àã
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;à¨á®¢ ­¨¥ § «¨â®£® ¯àאַ㣮«ì­¨ª , 2-ï ª®®à¤¨­ â  § ¤ ­  ¯® à §¬¥àã
	sz_buf2d_circle db 'buf2d_circle',0 ;à¨á®¢ ­¨¥ ®ªà㦭®áâ¨
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;ᦠ⨥ ¨§®¡à ¦¥­¨ï ¯® ¢ëá®â¥ ¢ 2 à §  (à §¬¥à ¡ãä¥à  ­¥ ¬¥­ï¥âáï)
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;ᦠ⨥ ¨§®¡à ¦¥­¨ï ¯® è¨à¨­¥ ¢ 2 à §  (à §¬¥à ¡ãä¥à  ­¥ ¬¥­ï¥âáï)
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0 
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
	sz_buf2d_draw_text db 'buf2d_draw_text',0
	sz_buf2d_crop_color db 'buf2d_crop_color',0
	sz_buf2d_offset_h db 'buf2d_offset_h',0
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
	sz_buf2d_get_pixel db 'buf2d_get_pixel',0
	sz_buf2d_vox_brush_create db 'buf2d_vox_brush_create',0
	sz_buf2d_vox_brush_delete db 'buf2d_vox_brush_delete',0
	sz_buf2d_vox_obj_get_img_w_3g db 'buf2d_vox_obj_get_img_w_3g',0
	sz_buf2d_vox_obj_get_img_h_3g db 'buf2d_vox_obj_get_img_h_3g',0
	sz_buf2d_vox_obj_draw_1g db 'buf2d_vox_obj_draw_1g',0
	sz_buf2d_vox_obj_draw_3g db 'buf2d_vox_obj_draw_3g',0
	sz_buf2d_vox_obj_draw_3g_scaled db 'buf2d_vox_obj_draw_3g_scaled',0
	sz_buf2d_vox_obj_draw_pl db 'buf2d_vox_obj_draw_pl',0
	sz_buf2d_vox_obj_draw_pl_scaled db 'buf2d_vox_obj_draw_pl_scaled',0
	sz_buf2d_vox_obj_draw_3g_shadows db 'buf2d_vox_obj_draw_3g_shadows',0