#include "AssembleIt.au3"




Func _ASM_Warp()
	_("use32");32Bit!

	_("push ebp")
	_("mov ebp, esp")
	_("sub esp, 84")

	_("mov esi, [ebp+8]");pPathArcLen
	_("mov edi, [ebp+12]");pPathPnt
	_("mov ecx, [ebp+16]");iSteps
	_("mov edx, [ebp+20]");fSize

	_("mov ebx, [edx]")
	_("mov [esp+76], ebx");store fSize
	_("mov ebx, [edx+4]")
	_("mov [esp+80], ebx");store fOffset

	;Get PathLen
	_("mov eax, [esi]");Cnt
	_("mov [esp+4], eax");store Max
	_("movd xmm7, [esi+4]");PathLen
	_("movdqa xmm6, xmm7")

	_("movd xmm5, ecx")
	_("cvtdq2ps xmm5, xmm5")
	_("divps xmm7, xmm5");= PathLen/Steps

	;xmm7 = 0,0,0,fMul
	;xmm6 = 0,0,0,PathLen
	;xmm5 = 0,0,0,fDist

	;esp:
	;80 = fOffset
	;76 = fSize
	;68 = store fY0, fX0
	;64 = store fDist
	;48 = 0.5,0.5,0.5,0.5
	;32 = 3,3,3,3
	;16 = Neg Msk 0,0,0x80000000,0
	;12 = store fPathlen
	; 8 = store fMul
	; 4 = MaxArcLen
	; 0 = Cnt

	_("mov eax, 0x80000000")
	_("movd xmm0, eax")
	_("movdqu [esp+16], xmm0")

	_("mov eax, 3")
	_("movd xmm0, eax")
	_("pshufd xmm0, xmm0, 0")
	_("cvtdq2ps xmm0, xmm0")
	_("movdqu [esp+32], xmm0")

	_("mov eax, 2")
	_("movd xmm1, eax")
	_("cvtdq2ps xmm1, xmm1")
	_("mov eax, 1")
	_("movd xmm0, eax")
	_("cvtdq2ps xmm0, xmm0")
	_("divss xmm0, xmm1")
	_("pshufd xmm0, xmm0, 0")
	_("movdqu [esp+48], xmm0")

	_("_LoopStep:")
		_("mov [esp], ecx");store Cnt
		_("movd xmm5, [edi]")
		_("movd xmm4, [esp+76]")
		_("mulss xmm5, xmm4")

		_("movq xmm0, [esp+80]");fOffset
		_("mulss xmm0, xmm6")
		_("addss xmm5, xmm0");Dist += fOffset

		_("xorps xmm4, xmm4")
		_("_LoopDistZero:")
			_("movdqa xmm3, xmm5")
			_("cmpltps xmm3, xmm4");Dist < 0
			_("movmskps ebx, xmm3")
			_("test ebx, 0xF")
			_("jz _LoopDistFull")
				_("addps xmm5, xmm6");Dist+=PathLen
				_("jmp _LoopDistZero")

		_("_LoopDistFull:")
			_("movdqa xmm3, xmm6")
			_("cmpltps xmm3, xmm5");PathLen < Dist
			_("movmskps ebx, xmm3")
			_("test ebx, 0xF")
			_("jz _FindDist")
				_("subps xmm5, xmm6");Dist-=PathLen
				_("jmp _LoopDistFull")

		_("_FindDist:")
			_("mov eax, 0");IdxLO
			_("mov ebx, [esp+4]");IdxHI = MaxArcLen
			_("_LoopFindDist:")
				_("mov ecx, ebx")
				_("sub ecx, eax")
				_("shr ecx, 1")
				_("add ecx, eax");Idx = iIdxLO + (($iIdxHI - $iIdxLO) / 2)
				_("mov edx, ecx")
				_("imul edx, 52")

				_("movd xmm4, [esi+edx+12]");ArcLen
				_("cmpltps xmm4, xmm5");ArcLen < fDist
				_("movmskps edx, xmm4")

				_("cmp eax, ebx")
				_("jge _FoundDist")

				_("test edx, 0xF")
				_("jnz _DistIdxLO")
					_("mov ebx, ecx")
					_("jmp _LoopFindDist")

				_("_DistIdxLO:")
					_("mov eax, ecx")
					_("add eax, 1")
					_("jmp _LoopFindDist")

		_("_FoundDist:")
			;If (DllStructGetData($tP2PDstData, "Values", $iIdx * 4 + 1) >= $fDstPos) Then $iIdx -= 1
			_("test edx, 0xF")
			_("jnz _IdxMinMax")
				_("sub ecx, 1")

			_("_IdxMinMax:")
				_("cmp ecx, 0")
				_("jge _ChkIdxMax")
					_("mov ecx, 0")
				_("_ChkIdxMax:")
					_("mov ebx, [esp+4]");MaxArcLen
					_("sub ebx, 1");------------------------------- 2 ?
					_("cmp ecx, ebx")
					_("jl _CalcVec")
						_("mov ecx, ebx")

	_("_CalcVec:")
		;xmm5 = fDist

		;eax =
		;ebx =
		;ecx = Idx
		;edx = IdxOff

		_("movd [esp+8], xmm7");store fMul
		_("movd [esp+12], xmm6");store fPathLen

		_("mov edx, ecx")
		_("imul edx, 52")
		_("mov eax, [esi+edx+20]")
		_("cmp eax, 3")
		_("je _Bezier")
			_("movdqu xmm6, [esi+edx+24]");Y1,X1,Y0,X0
			_("movd xmm4, [esi+edx+12]");ArcLen_0
			_("movd xmm3, [esi+edx+64]");ArcLen_1
			_("subss xmm3, xmm4");ArcLen_1 - ArcLen_0
			_("subss xmm5, xmm4");Dist - ArcLen_0
			_("divss xmm5, xmm3")
			_("pshufd xmm5, xmm5, 0")

			_("pshufd xmm2, xmm6, 0xEE");0,0,Y1,X1
			_("subps xmm2, xmm6");0,0,Y1-Y0,X1-X0
			_("movdqa xmm1, xmm2");0,0,VX,VY
			_("mulps xmm2, xmm5")

			_("addps xmm6, xmm2");=0,0,PX,PY

			_("pshufd xmm7, xmm1, 0x1");swap VX-VY
			_("movdqu xmm5, [esp+16]");Load NegMsk
			_("xorps xmm7, xmm5");Neg VY

			_("mulps xmm1, xmm1");0,0,VY^2,VX^2
			_("pshufd xmm0, xmm1, 0x55");0,0,0,VY^2
			_("addss xmm1, xmm0")
			_("sqrtss xmm1, xmm1")
			_("pshufd xmm1, xmm1, 0");0,0,Sqrt,Sqrt
			_("divps xmm7, xmm1");=0,0,VY,VX

			_("movd xmm2, [edi+4]");fY
			_("pshufd xmm2, xmm2, 0")
			_("mulps xmm2, xmm7")
			_("addps xmm2, xmm6")
			_("movq [edi], xmm2")

			_("jmp _ContStep")

		_("_Bezier:")
			_("movdqu xmm0, [esp+32]");3,3,3,3

			_("movdqu xmm2, [esi+edx+40]");Y3,X3,Y2,X2
			_("movdqu xmm1, [esi+edx+24]");Y1,X1,Y0,X0
			_("movdqa xmm7, xmm1")
			_("shufps xmm7, xmm2, 0x4E");Y2,X2,Y1,X1
			_("mulps xmm7, xmm0");Y2*3,X2*3,Y1*3,X1*3

			_("movdqa xmm4, xmm1")
			_("shufps xmm4, xmm2, 0xE4");Y3,X3,Y0,X0

			_("mulps xmm1, xmm0");Y1*3,X1*3,Y0*3,X0*3
			_("movdqa xmm6, xmm7");Y2*3,X2*3,Y0*3,X0*3
			_("addps xmm6, xmm6");Y2*6,X2*6,Y1*6,X1*6
			_("shufps xmm6, xmm1, 0x44");fY0*3,fX0*3,fY1*6,fX1*6

			_("pshufd xmm2, xmm7, 0xEE");fY2*3,fX2*3,fY2*3,fX2*3

			;$fAX = $fX3 - $fX2*3 + $fX1*3 - $fX0
			_("pshufd xmm1, xmm4, 0xEE");fY3,fX3,fY3,fX3
			_("subps xmm1, xmm2")
			_("addps xmm1, xmm7")
			_("subps xmm1, xmm4");=0,0,fAY,fAX

			;$fBX = $fX2*3 - $fX1*6 + $fX0*3
			_("subps xmm2, xmm6")
			_("pshufd xmm6, xmm6, 0xEE")
			_("addps xmm2, xmm6")

			;$fCX = $fX1*3 - $fX0*3
			_("movdqa xmm3, xmm7")
			_("subps xmm3, xmm6")

			_("movd [esp+64], xmm5");store fDist
			_("movq [esp+68], xmm4");store Y0, X0

			_("movd xmm7, [esi+edx+16]");fT
			_("movd xmm6, [esi+edx+16+52]");fT_Next

			_("subss xmm6, xmm7");fT-fTN
			_("movdqu xmm4, [esp+48]");0.5, 0.5, 0.5, 0.5
			_("mulss xmm6, xmm4");fZ /= 2
			_("addss xmm7, xmm6");fT += fZ
			_("mulss xmm6, xmm4");fZ /= 2

			_("movd eax, xmm7");store fT
			_("movd ebx, xmm6");store fZ

			;xmm7 =
			;xmm6 =
			;xmm5 =
			;xmm4 = 0.5,0.5,0.5,0.5
			;xmm3 = 0,0,fCY,fCX
			;xmm2 = 0,0,fBY,fBX
			;xmm1 = 0,0,fAY,fAX
			;xmm0 =

			_("mov ecx, 12")
			_("_LoopBezApprox:")
				_("movd xmm7, eax");restore fT

				_("pshufd xmm0, xmm7, 0xF0");0,0,fT,fT
				_("mulss xmm0, xmm7");0,0,fT,fT^2
				_("pshufd xmm0, xmm0, 0xD0");0,fT,fT^2,fT^2
				_("mulss xmm0, xmm7");0,fT,fT^2,fT^3

				_("movdqa xmm7, xmm1")
				_("pshufd xmm0, xmm0, 0x90");fT,fT^2, fT^3,fT^3
				_("mulps xmm7, xmm0");0,0, fAY*fT^3, fAX*fT^3

				_("movdqa xmm6, xmm2")
				_("pshufd xmm0, xmm0, 0xEA");fT,fT^2,fT^2,fT^2
				_("mulps xmm6, xmm0");0,0, fBY*fT^2, fBX*fT^2

				_("movdqa xmm5, xmm3")
				_("pshufd xmm0, xmm0, 0xFF");fT,fT,fT,fT
				_("mulps xmm5, xmm0");0,0, fCY*fT, fCX*fT

				;$fPX = $fAX * $fT ^ 3 + $fBX * $fT ^ 2 + $fCX * $fT + $fX0
				;$fPY = $fAY * $fT ^ 3 + $fBY * $fT ^ 2 + $fCY * $fT + $fY0
				_("addps xmm7, xmm6");+=fBX*fT^2
				_("addps xmm7, xmm5");+=fCX*fT

				_("movq xmm5, [esp+68]");load fY0,fX0
				_("addps xmm7, xmm5");+= fX0 ==============> fPY, fPX

				_("sub ecx, 1")
				_("cmp ecx, 0")
				_("jle _CalcBezVec")

				;xmm7 = 0,0,fPY,fPX
				;xmm6 =
				;xmm5 =
				;xmm4 = 0.5,0.5,0.5,0.5
				;xmm3 = 0,0,fCY,fCX
				;xmm2 = 0,0,fBY,fBX
				;xmm1 = 0,0,fAY,fAX
				;xmm0 = fT,fT,fT,fT

				;$fLenTmp = $fLenOff + Sqrt(($fPX - $fPXL) ^ 2 + ($fPY - $fPYL) ^ 2)
				_("movq xmm6, [esi+edx+56]");fPY,fPX

				_("subps xmm7, xmm6")
				_("mulps xmm7, xmm7")
				_("pshufd xmm6, xmm7, 0x55")
				_("addss xmm7, xmm6")
				_("sqrtss xmm7, xmm7")

				_("movd xmm6, [esi+edx+12]");ArcLen
				_("addss xmm6, xmm7");=fLenTmp
				#cs
				If $fLenTmp > $fDstPos Then
					$fT -= $fZ
				Else
					$fT += $fZ
				EndIf
				#ce
				_("movd xmm5, ebx");restore fZ

				_("movd xmm7, [esp+64]");restore fDist

				_("cmpltps xmm7, xmm6")
				_("movmskps eax, xmm7")
				_("test eax, 0xF")
				_("jz _fTAdd")
					_("subss xmm0, xmm5");fT-=fZ
					_("jmp _ContBezApprox")

				_("_fTAdd:")
					_("addss xmm0, xmm5");fT+=fZ

				_("_ContBezApprox:")
					_("mulss xmm5, xmm4");fZ /= 2
					_("movd ebx, xmm5");store fZ
					_("movd eax, xmm0");store fT
					_("jmp _LoopBezApprox")


				_("_CalcBezVec:")
					#cs
					Local $fTX = 3*$fAX*$fT^2 + 2*$fBX*$fT + $fCX
					Local $fTY = 3*$fAY*$fT^2 + 2*$fBY*$fT + $fCY
					Local $fM = Sqrt($fTX^2 + $fTY^2)

					$fVX = -$fTY / $fM
					$fVY = $fTX / $fM
					#ce

					_("movd xmm6, eax");restore fT
					_("pshufd xmm0, xmm6, 0xF0");0,0,fT,fT
					_("mulss xmm0, xmm6");0,0,fT,fT^2
					_("pshufd xmm0, xmm0, 0x50");fT,fT,fT^2,fT^2

					_("movdqu xmm6, [esp+32]");3,3,3,3

					_("mulps xmm1, xmm6");AX*=3
					_("mulps xmm1, xmm0");AX*=fT^2
					_("psrldq xmm0, 8")
					_("addps xmm2, xmm2");BX*=2
					_("mulps xmm2, xmm0");BX*=fT

					_("addps xmm1, xmm2")
					_("addps xmm1, xmm3");+=CX ====> TY, TX

					_("movdqa xmm0, xmm1")
					_("mulps xmm0, xmm0");^2

					_("pshufd xmm2, xmm0, 0x55");TY, TY
					_("addss xmm0, xmm2")
					_("sqrtss xmm0, xmm0")
					_("pshufd xmm0, xmm0, 0")

					_("divps xmm1, xmm0")

					_("pshufd xmm1, xmm1, 0x1");swap VX-VY
					_("movdqu xmm5, [esp+16]");Load NegMsk
					_("xorps xmm1, xmm5");Neg VY

					_("movd xmm2, [edi+4]");fY
					_("pshufd xmm2, xmm2, 0")
					_("mulps xmm2, xmm1")
					_("addps xmm2, xmm7")
					_("movq [edi], xmm2")


		_("_ContStep:")
			_("movd xmm7, [esp+8]");restore fMul
			_("movd xmm6, [esp+12]");restore fPathLen

		_("add edi, 8")
		_("mov ecx, [esp]");restore Cnt
		_("sub ecx, 1")
		_("ja _LoopStep")


	_("_Exit:")
		_("add esp, 84")
		_("pop ebp")
	_("ret ")

EndFunc




Func _ASM_CalcLen()
	_("use32");32Bit!

	_("push ebp")
	_("mov ebp, esp")

	_("mov esi, [ebp+8]");pPathPnt
	_("mov edi, [ebp+12]");pPathType
	_("mov ecx, [ebp+16]");iPathCnt
	_("mov edx, [ebp+20]");pPathArcLen

	_("add edx, 8")
	_("mov eax, [edx]");Get Prec
	_("add edx, 4")
	_("movd xmm7, eax")
	;xmm7 = 0,0,0,Prec

	_("sub esp, 12")
	;float ArcLen; float fT; uint Type; float Pnt[8];
	_("_LoopPrep:")
		_("mov ax, [edi]");AX = Type+1,Type
		_("cmp al, 0")
		_("jnz _NoStart")
			_("movq xmm6, [esi]")
			_("movq [esp], xmm6")
			_("mov [esp+8], ecx")

		_("_NoStart:")
		_("mov bl, ah")
		_("and bl, 0x3")
		_("cmp bl, 3")
		_("je _BezierPrep")
			_("add edx, 8")
			_("mov dword[edx], 1")
			_("movdqu xmm6, [esi]");Y1,X1,Y0,X0

			_("add edx, 4")
			_("movdqu [edx], xmm6")
			_("add edx, 40")

			_("add esi, 8");PathPnt + 8
			_("add edi, 1");PathType + 1
			_("sub ecx, 1")
			_("jmp _ContPrep")

		_("_BezierPrep:")
			_("mov dword[edx], 3")
			_("movdqu xmm6, [esi]");Y1,X1,Y0,X0
			_("movdqu xmm5, [esi+16]");Y3,X3,Y2,X2
			_("mov ebx, 0");PrecStep
			_("movd eax, xmm7");Prec
			_("_LoopBezPrep:")
				_("add edx, 4")
				_("mov [edx], ebx")
				_("add edx, 4")
				_("mov dword[edx], 3")
				_("add edx, 4")
				_("movdqu [edx], xmm6")
				_("add edx, 16")
				_("movdqu [edx], xmm5")
				_("add edx, 24")
				_("add ebx, 1")
				_("cmp ebx, eax");Prec
				_("jbe _LoopBezPrep")
			_("add esi, 24");PathPnt + 24
			_("add edi, 3");PathType + 3
			_("sub ecx, 3")
			_("mov ah, [edi]");AX = Type+1,Type

		_("_ContPrep:")
			_("test ah, 0x80")
			_("jz _NoClosed")
				_("mov ebx, [esp+8]");Restore Idx0
				_("sub ebx, ecx")
				_("cmp ebx, 1")
				_("jle _NoClosed")

				_("add edx, 8")
				_("mov dword[edx], 2")

				_("movq xmm0, [esi]")
				_("movq xmm1, [esp]")
				_("pslldq xmm1, 8")
				_("por xmm1, xmm0")

				_("add edx, 4")
				_("movdqu [edx], xmm1")
				_("add edx, 40")

		_("_NoClosed:")
		_("cmp ecx, 1")
		_("jg _LoopPrep")

	_("mov dword[edx], -1");Terminate

	_("mov esi, [ebp+20]");pPathArcLen
	_("add esi, 8")
	_("movd xmm0, [esi]")
	_("cvtdq2ps xmm0, xmm0");= Prec
	_("add esi, 4")

	_("mov ecx, 0")
	_("_LoopPrec:")
		_("mov eax, [esi]")
		_("add esi, 4")
		_("cmp eax, 0")
		_("jl _ExitPrec")

		_("movd xmm1, [esi]")
		_("cvtdq2ps xmm1, xmm1");= PrecStep

		_("divss xmm1, xmm0")
		_("movd [esi], xmm1")

		_("add esi, 48")
		_("add ecx, 1")
		_("jmp _LoopPrec")

	_("_ExitPrec:")
		_("mov esi, [ebp+20]");pPathArcLen
		_("mov [esi], ecx")

	;xmm7 = 0,0,0,ArcLen
	;xmm6 = Y1,X1,Y0,X0
	;xmm5 = Y3,X3,Y2,X2
	;xmm4 = 3,3,3,3

	_("mov eax, 3")
	_("movd xmm4, eax")
	_("cvtdq2ps xmm4, xmm4")
	_("pshufd xmm4, xmm4, 0");=3,3,3,3

	_("pxor xmm7, xmm7");Reset ArcLen
	_("add esi, 12")
	_("movq xmm0, [esi+12]")
	_("movq [esp], xmm0")

	_("_LoopLen:")
		_("mov eax, [esi+8]")
		_("cmp eax, 3")
		_("je _BezierLen")
			;ArcLen += Sqrt((X1-X0)^2 + (Y1-Y0)^2)
			_("movdqu xmm6, [esi+12]");Y1,X1,Y0,X0
			_("pshufd xmm5, xmm6, 0xEE");Y1,X1,Y1,X1
			_("movq [esp], xmm5");Save Last Point

			_("subps xmm5, xmm6")
			_("mulps xmm5, xmm5")
			_("pshufd xmm6, xmm5, 0xFD");0,0,0,Y1
			_("addss xmm5, xmm6")

			_("sqrtss xmm5, xmm5")

			_("movd eax, xmm7")
			_("mov [esi], eax");Write ArcLen

			_("addss xmm7, xmm5")
			_("jmp _ContLen")

		_("_BezierLen:")
			_("movdqu xmm6, [esi+12]");Y1,X1,Y0,X0
			_("movdqu xmm5, [esi+28]");Y3,X3,Y2,X2

			;$fAX = $fX3 - 3 * $fX2 + 3 * $fX1 - $fX0
			_("movdqa xmm2, xmm5")
			_("mulps xmm2, xmm4");=Y3*3,X3*3,Y2*3,X2*3
			_("pshufd xmm3, xmm5, 0xEE");Y3,X3,Y3,X3
			_("subps xmm3, xmm2");= -X2*3
			_("subps xmm3, xmm6");= -X0
			_("pshufd xmm0, xmm6, 0xEE")
			_("mulps xmm0, xmm4");=Y1*3,X1*3,Y1*3,X1*3
			_("addps xmm3, xmm0");= +X1*3 = 0,0,AY,AX <---

			;xmm7 = 0,0,0,ArcLen
			;xmm6 = Y1,X1,Y0,X0
			;xmm5 = Y3,X3,Y2,X2
			;xmm4 = 3,3,3,3
			;xmm3 = 0,0,AY,AX
			;xmm2 = Y3*3,X3*3,Y2*3,X2*3
			;xmm1 =
			;xmm0 = Y1*3,X1*3,Y1*3,X1*3

			;$fCX = 3 * $fX1 - 3 * $fX0
			_("movdqa xmm1, xmm0");=Y1*3,X1*3,Y1*3,X1*3
			_("movdqa xmm5, xmm0")
			_("movdqa xmm0, xmm6")
			_("mulps xmm0, xmm4");= Y1*3,X1*3,Y0*3,X0*3
			_("subps xmm1, xmm0");= 0,0,CY,CX <---

			;xmm7 = 0,0,0,ArcLen
			;xmm6 = Y1,X1,Y0,X0
			;xmm5 = Y1*3,X1*3,Y1*3,X1*3
			;xmm4 = 3,3,3,3
			;xmm3 = 0,0,AY,AX
			;xmm2 = Y3*3,X3*3,Y2*3,X2*3
			;xmm1 = 0,0,CY,CX
			;xmm0 = Y1*3,X1*3,Y0*3,X0*3

			;$fBX = 3 * $fX2 - 6 * $fX1 + 3 * $fX0
			_("addps xmm2, xmm0")
			_("addps xmm5, xmm5");= Y1*6,X1*6,Y1*6,X1*6
			_("subps xmm2, xmm5");= 0,0,BY,BX <---

			;xmm7 = 0,0,0,ArcLen
			;xmm6 = Y1,X1,Y0,X0
			;xmm5 = Y1*6,X1*6,Y1*6,X1*6
			;xmm4 = 3,3,3,3
			;xmm3 = 0,0,AY,AX
			;xmm2 = 0,0,BY,BX
			;xmm1 = 0,0,CY,CX
			;xmm0 = Y1*3,X1*3,Y0*3,X0*3

			;$fPX = $fAX * $fT ^ 3 + $fBX * $fT ^ 2 + $fCX * $fT + $fX0
			_("mov ebx, [esi+4]");fT
			_("movd xmm5, ebx")
			_("mov ebx, 1")
			_("movd xmm0, ebx")
			_("cvtdq2ps xmm0, xmm0")
			_("pshufd xmm0, xmm0, 0x3")
			_("por xmm5, xmm0");= 1,1,1,fT
			_("pshufd xmm0, xmm5, 0xF0");= 1,1,fT,fT
			_("mulps xmm0, xmm5");= 1,1,fT,fT^2
			_("pshufd xmm0, xmm0, 0xD0");= 1,fT,fT^2,fT^2
			_("mulps xmm0, xmm5");= 1,fT,fT^2,fT^3

			_("pshufd xmm5, xmm0, 0")
			_("mulps xmm3, xmm5");= AX*fT^3

			_("pshufd xmm5, xmm0, 0x55")
			_("mulps xmm2, xmm5");= BX*fT^2

			_("pshufd xmm5, xmm0, 0xAA")
			_("mulps xmm1, xmm5");= CX*fT^1

			_("addps xmm1, xmm2")
			_("addps xmm1, xmm3")
			_("addps xmm1, xmm6");= 0,0,PY,PX
			_("movq [esi+44], xmm1");write fPY, fPX

			;$fPathLen += Sqrt(($fPX - $fPXL) ^ 2 + ($fPY - $fPYL) ^ 2)
			_("movq xmm0, [esp]");Get First Point
			_("movq [esp], xmm1");Store Last Point

			_("subps xmm1, xmm0")
			_("mulps xmm1, xmm1")
			_("pshufd xmm0, xmm1, 0x1")
			_("addss xmm1, xmm0")

			_("sqrtss xmm1, xmm1")
			_("addss xmm7, xmm1")

			_("movd eax, xmm7")
			_("mov [esi], eax");Write ArcLen

		_("_ContLen:")

		_("add esi, 52")
		_("sub ecx, 1")
		_("ja _LoopLen")

	_("movd [esi], xmm7");Write ArcLen
	_("mov esi, [ebp+20]");pPathArcLen
	_("movd [esi+4], xmm7");Write ArcLen

	_("_Exit:")
		_("add esp, 12")
		_("pop ebp")
	_("ret ")
EndFunc



Func _ASM_BezierSubDiv()
	_("use32");32Bit!

	_("push ebp")
	_("mov ebp, esp")
	_("sub esp, 56")

	_("mov esi, [ebp+8]");pPathData => uint Cnt; float Pnt[Cnt*2]; byte Type[Cnt]
	_("mov ecx, [esi]")

	_("add esi, 4");= pPathPnt
	_("mov [esp+4], esi");store pPathPnt

	_("mov edx, ecx")
	_("shl edx, 3")
	_("mov edi, esi")
	_("add edi, edx");= pPathType
	_("mov [esp+8], edi")

	_("mov edi, [ebp+12]")
	_("mov [esp+12], edi");store pSubPnt

	_("mov edi, [ebp+16]")
	_("mov [esp+16], edi");store pSubType

	_("mov eax, [ebp+20]")
	_("mov ebx, eax")
	_("sub ebx, 1")
	_("add eax, 1")
	_("mov [esp+20], ebx");store iSubDiv-1

	_("movd xmm7, eax")
	_("pshufd xmm7, xmm7, 0")
	_("cvtdq2ps xmm7, xmm7")

	_("mov eax, 1")
	_("movd xmm6, eax")
	_("pshufd xmm6, xmm6, 0")
	_("cvtdq2ps xmm6, xmm6")

	_("mov dword[esp], 0");reset SubDivCnt

	;xmm7 = SubDiv+1, SubDiv+1, SubDiv+1, SubDiv+1
	;xmm6 = 1, 1, 1, 1

	;eax = T3, T2, T1, T0
	;ebx =
	;ecx = iPathCnt
	;edx = iSubDiv

	;esp:
	;+  0 = iSubDivCnt
	;+  4 = pPathPnt
	;+  8 = pPathType
	;+ 12 = pSubPnt
	;+ 16 = pSubType
	;+ 20 = iSubDiv-1
	;+ 24 = Y3, X3, Y2, X2, Y1, X1, Y0, X0

	_("_LoopBez:")
		_("mov esi, [esp+4]");restore PathPnt
		_("mov edi, [esp+8]");restore PathType

		_("movdqu xmm5, [esi]");Y1, X1, Y0, X0
		_("movdqu [esp+24], xmm5")
		_("movdqu xmm5, [esi+16]");Y3, X3, Y2, X2
		_("movdqu [esp+40], xmm5")
		_("mov eax, [edi]");T3, T2, T1, T0

		_("mov ebx, eax")
		_("rol ebx, 8")
		_("test bl, 0x80")
		_("jz _NextPathPnt")
			_("add esi, 8")
			_("add edi, 1")
			_("sub ecx, 1")

		_("_NextPathPnt:")
			_("add esi, 24")
			_("add edi, 3")
			_("sub ecx, 3")
			_("mov [esp+4], esi");store pPathPnt
			_("mov [esp+8], edi");store pPathType


		_("mov esi, [esp+12]");restore SubPnt
		_("mov edi, [esp+16]");restore SubType

		_("movdqa xmm4, xmm7")
		_("mov edx, [esp+20]");iSubDiv
		_("_LoopSubDiv:")
			_("subps xmm4, xmm6")
			_("movdqa xmm5, xmm6")
			_("divps xmm5, xmm4");fT, fT, fT, fT

			;$fA + ($fB - $fA) * $fT

			;DllStructSetData($tBezPnt, 1, $fX0, $iBezCnt*2+1)
			;DllStructSetData($tBezPnt, 1, $fY0, $iBezCnt*2+2)
			_("movdqu xmm0, [esp+24]");load fY1, fX1, fY0, fX0
			_("movq [esi], xmm0");fY0, fX0

			;$aTempX[0] = _CalcPoint($fX0, $fX1, $fT)
			;$aTempY[0] = _CalcPoint($fY0, $fY1, $fT)
			;$aTempX[2] = _CalcPoint($fX1, $fX2, $fT)
			;$aTempY[2] = _CalcPoint($fY1, $fY2, $fT)
			_("movdqu xmm3, [esp+32]");load fY2, fX2, fY1, fX1
			_("subps xmm3, xmm0")
			_("mulps xmm3, xmm5")
			_("addps xmm3, xmm0");fTY2, fTX2, fTY0, fTX0

			;DllStructSetData($tBezPnt, 1, $aTempX[0], $iBezCnt*2+3)
			;DllStructSetData($tBezPnt, 1, $aTempY[0], $iBezCnt*2+4)
			_("movq [esi+8], xmm3");write fTY0, fTX0

			;$aTempX[3] = _CalcPoint($aTempX[0], $aTempX[2], $fT)
			;$aTempY[3] = _CalcPoint($aTempY[0], $aTempY[2], $fT)
			;$aTempX[1] = _CalcPoint($fX2, $fX3, $fT)
			;$aTempY[1] = _CalcPoint($fY2, $fY3, $fT)
			_("movdqu xmm0, [esp+40]");fY3, fX3, fY2, fX2
			_("movdqa xmm2, xmm3")
			_("shufps xmm2, xmm0, 0xEE");fY3, fX3, fTY2, fTX2
			_("movdqa xmm1, xmm3")
			_("shufps xmm1, xmm0, 0x44");fY2, fX2, fTY0, fTX0
			_("subps xmm2, xmm1")
			_("mulps xmm2, xmm5")
			_("addps xmm2, xmm1");fTY1, fTX1, fTY3, fTX3


			;DllStructSetData($tBezPnt, 1, $aTempX[3], $iBezCnt*2+5)
			;DllStructSetData($tBezPnt, 1, $aTempY[3], $iBezCnt*2+6)
			_("movq [esi+16], xmm2");write fTY3, fTX3

			;$aTempX[4] = _CalcPoint($aTempX[2], $aTempX[1], $fT)
			;$aTempY[4] = _CalcPoint($aTempY[2], $aTempY[1], $fT)
			_("pshufd xmm1, xmm2, 0xEE");fTY1, fTX1, fTY1, fTX1
			_("pshufd xmm0, xmm3, 0xEE");fTY2, fTX2, fTY2, fTX2
			_("subps xmm1, xmm0")
			_("mulps xmm1, xmm5")
			_("addps xmm1, xmm0");fTY4, fTX4, fTY4, fTX4

			;$aTempX[5] = _CalcPoint($aTempX[3], $aTempX[4], $fT)
			;$aTempY[5] = _CalcPoint($aTempY[3], $aTempY[4], $fT)
			_("movdqa xmm0, xmm1")
			_("subps xmm0, xmm2")
			_("mulps xmm0, xmm5")
			_("addps xmm0, xmm2"); -, -, fTY5, fTX5

			;xmm7 = SubDiv+1, SubDiv+1, SubDiv+1, SubDiv+1
			;xmm6 = 1, 1, 1, 1
			;xmm5 = fT, fT, fT, fT
			;xmm4 = fTmp, fTmp, fTmp, fTmp
			;xmm3 = fTY2, fTX2, fTY0, fTX0
			;xmm2 = fTY1, fTX1, fTY3, fTX3
			;xmm1 = fTY4, fTX4, fTY4, fTX4
			;xmm0 = ----, ----, fTY5, fTX5

			;$fX0 = $aTempX[5]
			;$fY0 = $aTempY[5]
			_("movq [esp+24], xmm0");write fTY5, fTX5
			;$fX1 = $aTempX[4]
			;$fY1 = $aTempY[4]
			_("movq [esp+32], xmm1");write fTY4, fTX4
			;$fX2 = $aTempX[1]
			;$fY2 = $aTempY[1]
			_("psrldq xmm2, 8")
			_("movq [esp+40], xmm2");write fTY1, fTX1


			;DllStructSetData($tBezType, 1, $iT0, $iBezCnt+1)
			;DllStructSetData($tBezType, 1, $iT1, $iBezCnt+2)
			;DllStructSetData($tBezType, 1, $iT2, $iBezCnt+3)
			_("mov ebx, eax")
			_("mov [edi], bx")
			_("ror ebx, 16")
			_("mov [edi+2], bl")

			;$iT0 = $iT1
			_("mov al, ah")

			;$iBezCnt += 3
			_("add dword[esp], 3")

			_("add esi, 24")
			_("add edi, 3")

			_("sub edx, 1")
			_("jg _LoopSubDiv")

		;DllStructSetData($tBezPnt, 1, $fX0, $iBezCnt*2+1)
		;DllStructSetData($tBezPnt, 1, $fY0, $iBezCnt*2+2)
		;DllStructSetData($tBezPnt, 1, $fX1, $iBezCnt*2+3)
		;DllStructSetData($tBezPnt, 1, $fY1, $iBezCnt*2+4)
		;DllStructSetData($tBezPnt, 1, $fX2, $iBezCnt*2+5)
		;DllStructSetData($tBezPnt, 1, $fY2, $iBezCnt*2+6)
		;DllStructSetData($tBezPnt, 1, $fX3, $iBezCnt*2+7)
		;DllStructSetData($tBezPnt, 1, $fY3, $iBezCnt*2+8)
		_("movdqu xmm0, [esp+24]");fY1, fX1, fY0, fX0
		_("movdqu xmm1, [esp+40]");fY3, fX3, fY2, fX2
		_("movdqu [esi], xmm0")
		_("movdqu [esi+16], xmm1")

		;DllStructSetData($tBezType, 1, $iT1, $iBezCnt+1)
		;DllStructSetData($tBezType, 1, $iT1, $iBezCnt+2)
		;DllStructSetData($tBezType, 1, $iT2, $iBezCnt+3)
		;DllStructSetData($tBezType, 1, $iT3, $iBezCnt+4)
		_("mov [edi], eax")


		;If BitAND($iT3, 0x80) Then $iBezCnt += 1
		_("rol eax, 8")
		_("test al, 0x80")
		_("jz _TestEnd")
			_("add dword[esp], 1")
			_("add esi, 8")
			_("add edi, 1")
			_("jmp _NoClosed")

		_("_TestEnd:")
			_("cmp ecx, 1")
			_("jg _NoClosed")
				_("add dword[esp], 1")
				_("add esi, 8")
				_("add edi, 1")
		;$iBezCnt += 3
		_("_NoClosed:")
			_("add dword[esp], 3")
			_("add esi, 24")
			_("add edi, 3")


		_("mov [esp+12], esi");store pSubPnt
		_("mov [esp+16], edi");store pSubType

		_("cmp ecx, 1")
		_("jg _LoopBez")

	_("_Exit:")
		_("mov eax, [esp]");Return BezCnt
	_("add esp, 56")
	_("pop ebp")
	_("ret ")
EndFunc















Func _ASM_PathToBezier()
	_("use32");32Bit!

	_("push ebp")
	_("mov ebp, esp")
	_("sub esp, 12")

	_("mov esi, [ebp+8]");pPathData => uint Cnt; float Pnt[Cnt*2]
	_("mov ecx, [esi]")
	_("add esi, 4");= pPathPnt

	_("mov edi, [ebp+12]");pPathType => byte Type[Cnt]
	_("mov edx, [ebp+16]");pBezPnt => float Pnt[Cnt*8]
	_("mov ebx, [ebp+20]");pBezType => byte Type[Cnt*4]

	_("mov eax, 0")
	_("mov [esp], eax");reset BezCnt

	_("mov eax, 1")
	_("movd xmm7, eax")
	_("cvtdq2ps xmm7, xmm7")
	_("mov eax, 3")
	_("movd xmm6, eax")
	_("cvtdq2ps xmm6, xmm6")
	_("divss xmm7, xmm6");1/3
	_("movdqa xmm6, xmm7")
	_("addss xmm6, xmm6");0.666
	_("shufps xmm7, xmm6, 0");= 0.666, 0.666, 0.333, 0.333

	;esp:
	;+  0 = BezCnt
	;+  4 = StartX
	;+  8 = StartY

	;eax = 0, 0, T1, T0
	;ebx = pBezType
	;ecx = Cnt
	;edx = pBezPnt
	;esi = PathPnt
	;edi = PathType

	;xmm7 = 0.666, 0.666, 0.333, 0.333

	_("_LoopPathToBez:")
		_("mov ax, [edi]");Type1, Type0
		_("cmp al, 0")
		_("jnz _ChkType1")
			_("movq xmm6, [esi]");PathPnt Y0, X0
			_("movq [esp+4], xmm6");store StartY, StartX

			_("movq [edx], xmm6");write BezPnt
			_("add edx, 8")

			_("mov byte[ebx], 0");write type = 0
			_("add ebx, 1")

			_("add dword[esp], 1");BezCnt += 1


		_("_ChkType1:")
			_("cmp ah, 0")
			_("jz _ChkClosed")
				_("mov al, ah")
				_("and al, 0x3")
				_("cmp al, 0x3")
				_("je _Bezier")

				_("_Line:")
					_("movdqu xmm6, [esi]");Y1, X1, Y0, X0
					_("pshufd xmm5, xmm6, 0xEE");Y1, X1, Y1, X1
					_("movq [edx+16], xmm5");Write Bez Y3, X3

					_("subps xmm5, xmm6");0, 0, Y1-Y0, X1-X0
					_("pshufd xmm5, xmm5, 0x44");Y1-Y0, X1-X0, Y1-Y0, X1-X0
					_("mulps xmm5, xmm7");*0.666, 0.666, 0.333, 0.333

					_("pshufd xmm6, xmm6, 0x44");Y0, X0, Y0, X0
					_("addps xmm6, xmm5");Y0+(Y1-Y0)*0.666, X0+(X1-X0)*0.666, Y0+(Y1-Y0)*0.333, X0+(X1-X0)*0.333
					_("movdqu [edx], xmm6");Write Bez Y2, X2, Y1, X1
					_("add edx, 24")

					_("mov dword[ebx], 0x00030303");Write Type 03 03 03
					_("add ebx, 3")

					_("add dword[esp], 3");BezCnt += 3
					_("jmp _ChkClosed")

				_("_Bezier:")
					_("movq xmm6, [esi+8]");Y1, X1
					_("movq [edx], xmm6")
					_("add edx, 8")

					_("mov byte[ebx], 0x3")
					_("add ebx, 1")

					_("add dword[esp], 1");BezCnt += 1

			_("_ChkClosed:")
				_("test ah, 0x80")
				_("jz _ContLoop")
					_("movq xmm6, [esi+8]");Y0, X0
					_("movq xmm5, [esp+4]");Y3, X3

					_("movdqa xmm4, xmm5")
					_("subps xmm4, xmm6");Y3-Y0, X3-X0
					_("pshufd xmm4, xmm4, 0x44");Y3-Y0, X3-X0, Y3-Y0, X3-X0
					_("mulps xmm4, xmm7");*0.666, 0.666, 0.333, 0.333

					_("pshufd xmm6, xmm6, 0x44");Y0, X0, Y0, X0
					_("addps xmm6, xmm4")

					_("movdqu [edx], xmm6")
					_("movq [edx+16], xmm5")
					_("add edx, 24")

					_("mov dword[ebx], 0x00830303")
					_("add ebx, 3")

					_("add dword[esp], 3");BezCnt += 3

		_("_ContLoop:")
			_("add esi, 8");next PathPoint
			_("add edi, 1");next PathType

		_("sub ecx, 1")
		_("ja _LoopPathToBez")


	_("_Exit:")
		_("mov eax, [esp]");Return BezCnt
	_("add esp, 12")
	_("pop ebp")
	_("ret ")
EndFunc