		.386p
		ASSUME	CS:CODE,DS:DATA
		INCLUDE	YGHASM.H

		PUBLIC	YGH_polygonArea


SUBABS		MACRO	AREG,BREG
		LOCAL	L0
		SUB	AREG,BREG
		JG	SHORT L0
		NEG	AREG
L0:
		ENDM	


CLIP		MACRO	CPP
;Y=(X-X1)(Y2-Y1)/(X2-X1)+Y1
		SUB	EDX,EBX		;EDX=Y2-Y1
		SUB	ECX,EAX		;ECX=X2-X1
		SUB	EAX,CPP		;EAX=(X1-X)*-1
		NEG	EAX		;   = X-X1
		IMUL	EDX		;EAX:EDX=(X-X1)(Y2-Y1)
		IDIV	ECX		;EAX=(X-X1)(Y2-Y1)/(X2-X1)
		ADD	EAX,EBX		;EAX=(X-X1)(Y2-Y1)/(X2-X1)+Y1
		ENDM


CUTX		MACRO	XREG,LEFT,RIGHT
		LOCAL	L0,L1
		CMP	XREG,LEFT
		JGE	SHORT L0
		MOV	XREG,LEFT
		JMP	SHORT L1
		ALIGN	4
L0:
		CMP	XREG,RIGHT
		JL	L1		;JLEとするよりも速い
		MOV	XREG,RIGHT
L1:
		ENDM




CMPBUF		MACRO	STORE
		CMP	EAX,[ESI]
		JG	STORE
		MOVSD
		ENDM

;ADDBUF   EDI:ライン格納バッファ   EAX:追加する値
;         Direction Flag must be set
ADDBUF		MACRO
		LOCAL	JTBL
		LOCAL	L00,L01,L02,L03,L04,L05,L06,L07
		LOCAL	L08,L09,L10,L11,L12,L13,L14
		LOCAL	ERROR,TRANSEND

		PUSH	ECX
		PUSH	ESI
		PUSH	EDI

		MOV	ECX,[EDI]
		INC	DWORD PTR [EDI]
		LEA	ESI,[EDI+ECX*4]
		LEA	EDI,[ESI+4]
		JMP	CS:[JTBL+ECX*4]

		ALIGN	4
JTBL		DD	OFFSET L00,OFFSET L01,OFFSET L02,OFFSET L03
		DD	OFFSET L04,OFFSET L05,OFFSET L06,OFFSET L07
		DD	OFFSET L08,OFFSET L09,OFFSET L10,OFFSET L11
		DD	OFFSET L12,OFFSET L13,OFFSET ERROR
ERROR:		NEG	ECX
		LEA	EDI,[ESI+ECX*4]
		DEC	DWORD PTR [EDI]
		JMP	TRANSEND

		ALIGN	4
L13:		CMPBUF	L00
L12:		CMPBUF	L00
L11:		CMPBUF	L00
L10:		CMPBUF	L00
L09:		CMPBUF	L00
L08:		CMPBUF	L00
L07:		CMPBUF	L00
L06:		CMPBUF	L00
L05:		CMPBUF	L00
L04:		CMPBUF	L00
L03:		CMPBUF	L00
L02:		CMPBUF	L00
		ALIGN	4
L01:		MOVSD
		CMP	EAX,[EDI]
		SETG	CL		;0=<ECX<14 ∴MOVZX不要
		LEA	EDI,[EDI+ECX*4]
L00:		MOV	[EDI],EAX

TRANSEND:	POP	EDI
		POP	ESI
		POP	ECX
		ENDM


;ESI:AREA  EAX:X  EBX:Y1  EDX:Y2      EDI,EBX,ECX will be destroyed
VERTICAL	MACRO
		LOCAL	NOLOOP,VERTLOOP
		MOV	EDI,EBX
		SUBABS	EBX,EDX
		JE	NOLOOP
		SHL	EDI,YGH_XBUFSHIFT
		LEA	EDI,[ESI+EDI]
		MOV	ECX,[LVY]
		ALIGN	4
VERTLOOP:	ADD	EDI,ECX
		ADDBUF
		DEC	EBX
		JNE	VERTLOOP
NOLOOP:
		ENDM


;void polygon_normal(int *plg,int x1,int y1,int x2,int y2)
;{
;    int c,a,b,Rf;
;
;    a=_abs(x2-x1);
;    b=_abs(y2-y1);
;
;    c=_abs(y2-y1);
;    Rf=0;
;    if(a<b)
;    {
;        while(c>0)
;        {
;            y1+=vy;
;            Rf+=a;
;            polygon_addPoint(plg,x1,y1);
;            if(Rf>0)
;            {
;                x1+=vx;
;                Rf-=b;
;            }
;            c--;
;        }
;    }
;    else if(a>b)
;    {
;        while(c>0)
;        {
;            x1+=(Rf/b+1)*vx;
;            y1+=vy;
;            Rf=(Rf%b)-b+a;
;            polygon_addPoint(plg,x1,y1);
;            c--;
;        }
;    }
;    else if(a==b)
;    {
;        while(c>0)
;        {
;            x1+=vx;
;            y1+=vy;
;            polygon_addPoint(plg,x1,y1);
;            c--;
;        }
;    }
;}
;EAX:x  EDI:x,y Buffer Top
DXisMuchSmallerMacro	MACRO
		ADD	EDI,[LVY]
		ADDBUF
		ENDM


;EBX:DX  ECX:EY  EBP:LineCounter  ESI:Rf(0)  all registers will be destroyed
DXisLargerThanDYmacro	MACRO
		XCHG	EAX,ESI		;TEMP:  EAX=RF  ESI=X
		SUB	EDX,EDX
		IDIV	ECX		;TEMP:  EAX=RF/B  EDX=RF%B
		IMUL	EAX,[LVX]
		LEA	EAX,[ESI+EAX]	;EAX=X+(RF/B+1)*VX
		ADD	EDI,[LVY]
		LEA	ESI,[EDX+EBX]	;ESI=RF%B + A
		ADDBUF
		ENDM


;ESI:AREA    EAX,EBX,ECX,EDX:X1,Y1,X2,Y2
POLYGON_NORMAL	MACRO
		PUSHAD

		MOV	EDI,EBX
		SHL	EDI,YGH_XBUFSHIFT
		LEA	EDI,[ESI+EDI]		;ESI解放

		SUBABS	ECX,EAX
		SUBABS	EDX,EBX
		JE	qEXIT
		MOV	EBX,ECX		;EBX:a
		MOV	ECX,EDX		;ECX:b
		MOV	EBP,EDX		;EBP:c
		MOV	ESI,0		;ESI:Rf(a==bでは不使用)

		MOV	EDX,[LVY]	;EDX:VY(a>bでは不使用)

		LEA	ESI,[EBX*4]
		CMP	ESI,ECX
		MOV	ESI,0
		JLE	qDXisMuchSmaller	;a*4 < b == b/a > 4

		LEA	ESI,[ECX*4]
		CMP	EBX,ESI
		MOV	ESI,0
		JGE	qDXisMuchLarger		;a>=b*4 == b/a<=1/4

		CMP	EBX,ECX
		JE	qDXisAsSameAsDY
		JG	qDXisLargerThanDY

qDXisSmallerThanDY:
		MOV	EBP,EBX
		ALIGN	4
qDXisSmallerThanDYloop:
		ADD	EDI,EDX
		ADDBUF
		ADD	ESI,EBX
		JL	qDXisSmallerThanDYloop

		ADD	EAX,[LVX]
		SUB	ESI,ECX
		SUB	EBP,1
		JGE	qDXisSmallerThanDYloop
		JMP	qEXIT



		ALIGN	4
qJtblDXsDY	DD  OFFSET qDXsDY0,OFFSET qDXsDY1,OFFSET qDXsDY2,OFFSET qDXsDY3
 		DD  OFFSET qDXsDY4,OFFSET qDXsDY5,OFFSET qDXsDY6,OFFSET qDXsDY7
qDXisMuchSmaller:
		XCHG	EAX,ESI
		MOV	EDX,0
		IDIV	EBX
		ADD	EDX,ECX	;Rf%a +b

		XCHG	ESI,EDX
		XCHG	EDX,EAX
		SUB	EBP,EDX
		JL	qEXIT

		PUSH	ESI
		MOV	ESI,EDX
		AND	ESI,7
		JMP	CS:[qJtblDXsDY + ESI*4]
		ALIGN	4
qDXsDY8:	DXisMuchSmallerMacro
qDXsDY7:	DXisMuchSmallerMacro
qDXsDY6:	DXisMuchSmallerMacro
qDXsDY5:	DXisMuchSmallerMacro
qDXsDY4:	DXisMuchSmallerMacro
qDXsDY3:	DXisMuchSmallerMacro
qDXsDY2:	DXisMuchSmallerMacro
qDXsDY1:	DXisMuchSmallerMacro
qDXsDY0:	SUB	EDX,8
		JGE	qDXsDY8
		POP	ESI

		ADD	EAX,[LVX]
		JMP	qDXisMuchSmaller





		ALIGN	4
qDXisLargerThanDY:
		LEA	ESI,[EBX-1]	;？
		MOV	EDX,[LVX]
		ALIGN	4
qDXisLargerThanDYloop:
		ADD	EAX,EDX
		SUB	ESI,ECX
		JGE	qDXisLargerThanDYloop
		ADD	ESI,EBX
		ADD	EDI,[LVY]
		ADDBUF
		DEC	EBP
		JNE	qDXisLargerThanDYloop
		JMP	qEXIT





		ALIGN	4
qJtblDXlDY	DD  OFFSET qDXlDY0,OFFSET qDXlDY1,OFFSET qDXlDY2,OFFSET qDXlDY3
		DD  OFFSET qDXlDY4,OFFSET qDXlDY5,OFFSET qDXlDY6,OFFSET qDXlDY7
qDXisMuchLarger:
		MOV	ESI,EBX		;？
		MOV	EDX,EBP
		AND	EDX,7
		JMP	CS:[qJtblDXlDY + EDX*4]
		ALIGN	4
qDXlDY0:	DXisLargerThanDYmacro
qDXlDY7:	DXisLargerThanDYmacro
qDXlDY6:	DXisLargerThanDYmacro
qDXlDY5:	DXisLargerThanDYmacro
qDXlDY4:	DXisLargerThanDYmacro
qDXlDY3:	DXisLargerThanDYmacro
qDXlDY2:	DXisLargerThanDYmacro
qDXlDY1:	DXisLargerThanDYmacro
		SUB	EBP,8
		JG	qDXlDY0
		JMP	qEXIT




		ALIGN	4
qDXisAsSameAsDY:
		MOV	ESI,[LVX]
		ALIGN	4
qDXisAsSameAsDYloop:
		ADD	EAX,ESI
		ADD	EDI,EDX
		ADDBUF
		DEC	EBP
		JNE	qDXisAsSameAsDYloop

		ALIGN	4
qEXIT:		POPAD
		ENDM





DATA		SEGMENT
		ALIGN	4
FSTX		DD	0
FSTY		DD	0
FSTVY		DD	0
LSTVY		DD	0
MNX		DD	0
MNY		DD	0
MAX		DD	0
MAY		DD	0
LVX		DD	0
LVY		DD	0
DRAWF		DD	0		;b0:上下  b1:左  b2:右
DATA		ENDS


CODE		SEGMENT
;/* polygon_line  戻り値 0:画面外  1:画面内の点が存在 */
;int polygon_line(int *plg,int x1,int y1,int x2,int y2)
;{
;    int sp;            /* 書き出し点を追加するかしないかのフラッグ */
;    int ax,ay,bx,by;   /* 直線の変換用 */
;    int vx,vy;         /* 直線の方向ベクトル SGN(x2-x1),SGN(y2-y1) */
;
;    /* ↓ポリゴンの最大値/最小値のチェック (水平/垂直直線になる場合の備え) */
;    if(x2>max)max=x2;
;    if(x2<mnx)mnx=x2;
;    if(y2>may)may=y2;
;    if(y2<mny)mny=y2;
;
;
;    /* ↓両方の点が画面の上か下ならば何もしない */
;    if((y1<vy1 && y2<vy1) || (y1>vy2 && y2>vy2))return 0;
;
;
;    /* ↓ 上下にはみ出している部分を切る */
;    if(y1<vy1)
;    {
;        ax=clipPoint(y1,x1,y2,x2,vy1);
;        ay=vy1;
;    }
;    else if(y1>vy2)
;    {
;        ax=clipPoint(y1,x1,y2,x2,vy2);
;        ay=vy2;
;    }
;    else
;    {
;        ax=x1;
;        ay=y1;
;    }
;
;    if(y2<vy1)
;    {
;        bx=clipPoint(y1,x1,y2,x2,vy1);
;        by=vy1;
;    }
;    else if(y2>vy2)
;    {
;        bx=clipPoint(y1,x1,y2,x2,vy2);
;        by=vy2;
;    }
;    else
;    {
;        bx=x2;
;        by=y2;
;    }
;
;    x1=ax; y1=ay; x2=bx; y2=by;
;    /* ↑ 上下にはみ出している部分を切る */
;
;
;    if     (x2-x1 >0)vx= 1;
;    else if(x2-x1==0)vx= 0;
;    else if(x2-x1< 0)vx=-1;
;
;    if     (y2-y1 >0)vy= 1;
;    else if(y2-y1==0)vy= 0;
;    else if(y2-y1< 0)vy=-1;
;
;    if(lstvy*vy < 0)sp=1; else sp=0;
;
;
;    /* 水平でない直線ならばvyを記録 */
;    if(vy!=0)
;    {
;        lstvy=vy;
;        /* それが最初の縦の幅を持った直線ならば記録 */
;        if(fstvy==0)
;        {
;            if     (x1<vx1)fstx=vx1;
;            else if(x1>vx2)fstx=vx2;
;            else           fstx= x1;
;            fsty=y1;
;            fstvy=vy;
;        }
;    }
;
;    /* 両方とも左右にはみ出していないかのチェック */
;    if(x1<vx1 && x2<vx1)
;    {
;        if(sp)polygon_addPoint(plg,vx1,y1);
;        polygon_vertical(plg,vx1,y1,y2);
;        return 0;
;    }
;    else if(x1>vx2 && x2>vx2)
;    {
;        if(sp)polygon_addPoint(plg,vx2,y1);
;        polygon_vertical(plg,vx2,y1,y2);
;        return 0;
;    }
;
;
;    /* 水平な直線ならば何もしない */
;    if(vy==0)return 1;
;
;
;    /* 最初の点を追加する場合 */
;    if(sp)
;    {
;        if     (x1<vx1)polygon_addPoint(plg,vx1,y1);
;        else if(x1>vx2)polygon_addPoint(plg,vx2,y1);
;        else           polygon_addPoint(plg, x1,y1);
;    }
;
;
;    /* 垂直な直線の処理 */
;    if(x1==x2)
;    {
;        polygon_vertical(plg,x1,y1,y2);
;        return 1;
;    }
;
;
;    /* P1が左右にはみ出している場合 */
;    if(x1<vx1)
;    {
;        by=clipPoint(x1,y1,x2,y2,vx1);
;        polygon_vertical(plg,vx1,y1,by);
;        x1=vx1;
;        y1=by;
;    }
;    else if(x1>vx2)
;    {
;        by=clipPoint(x1,y1,x2,y2,vx2);
;        polygon_vertical(plg,vx2,y1,by);
;        x1=vx2;
;        y1=by;
;    }
;    
;
;    /* 画面内部の処理 */
;    if(vx1<=x2 && x2<=vx2)
;    {
;        bx=x2;
;        by=y2;
;    }
;    else if(x2<vx1)
;    {
;        bx=vx1;
;        by=clipPoint(x1,y1,x2,y2,vx1);
;    }
;    else if(vx2<x2)
;    {
;        bx=vx2;
;        by=clipPoint(x1,y1,x2,y2,vx2);
;    }
;    polygon_normal(plg,x1,y1,bx,by);
;
;
;    /* P2がはみ出していた場合の処理 */
;    if(by!=y2)
;    {
;        polygon_vertical(plg,bx,by,y2);
;    }
;
;    return 1;
;}
;EDI:PAGE   ESI:AREA   EAX,EBX,ECX,EDX:X1,Y1,X2,Y2
		ALIGN	4
POLYGON_LINE	PROC
#ESPOFS		EQU	52
#VY2		EQU	ESP+48
#VX2		EQU	ESP+44
#VY1		EQU	ESP+40
#VX1		EQU	ESP+36
#SP		EQU	ESP+32
#AX		EQU	ESP+28
#AY		EQU	ESP+24
#BX		EQU	ESP+20
#BY		EQU	ESP+16
#Y2		EQU	ESP+12
#X2		EQU	ESP+8
#Y1		EQU	ESP+4
#X1		EQU	ESP

		PUSH	ESI
		PUSH	EDI
		PUSH	EBP
		SUB	ESP,#ESPOFS


		CMP	ECX,[MAX]
		JL	#MAXNOCHANGE
		MOV	[MAX],ECX
#MAXNOCHANGE:
		CMP	ECX,[MNX]
		JG	#MNXNOCHANGE
		MOV	[MNX],ECX
#MNXNOCHANGE:
		CMP	EDX,[MAY]
		JL	#MAYNOCHANGE
		MOV	[MAY],EDX
#MAYNOCHANGE:
		CMP	EDX,[MNY]
		JG	#MNYNOCHANGE
		MOV	[MNY],EDX
#MNYNOCHANGE:

		MOV	EBP,[EDI+YGH_VX1]
		MOV	[#VX1],EBP
		MOV	EBP,[EDI+YGH_VY1]
		MOV	[#VY1],EBP
		MOV	EBP,[EDI+YGH_VX2]
		MOV	[#VX2],EBP
		MOV	EBP,[EDI+YGH_VY2]
		MOV	[#VY2],EBP


		CMP	EBX,[#VY1]
		JGE	#BOTHisnotUPPER
		CMP	EDX,[#VY1]
		JL	#XCHECK
#BOTHisnotUPPER:
		CMP	EBX,[#VY2]
		JLE	#BOTHisnotUNDER
		CMP	EDX,[#VY2]
		JG	#XCHECK
#BOTHisnotUNDER:

		AND	[DRAWF],DWORD PTR 0FEH

		MOV	[#X1],EAX
		MOV	[#Y1],EBX
		MOV	[#X2],ECX
		MOV	[#Y2],EDX

		XCHG	EAX,EBX
		XCHG	ECX,EDX

		CMP	EAX,[#VY1]
		JGE	SHORT #Y1isLargerThanVY1
		CLIP	[#VY1]
		MOV	[#AX],EAX
		MOV	EBX,[#VY1]
		MOV	[#AY],EBX
		JMP	SHORT #PT1isSettled
		ALIGN	4

#Y1isLargerThanVY1:
		CMP	EAX,[#VY2]
		JLE	SHORT #Y1isSmallerThanVY2
		CLIP	[#VY2]
		MOV	[#AX],EAX
		MOV	EBX,[#VY2]
		MOV	[#AY],EBX
		JMP	SHORT #PT1isSettled
		ALIGN	4
#Y1isSmallerThanVY2:
		MOV	[#AX],EBX
		MOV	[#AY],EAX
#PT1isSettled:


		MOV	EAX,[#Y1]
		MOV	EBX,[#X1]
		MOV	ECX,[#Y2]
		MOV	EDX,[#X2]

		CMP	ECX,[#VY1]
		JGE	SHORT #Y2isLargerThanVY1
		CLIP	[#VY1]
		MOV	[#BX],EAX
		MOV	EBX,[#VY1]
		MOV	[#BY],EBX
		JMP	SHORT #PT2isSettled
		ALIGN	4
#Y2isLargerThanVY1:
		CMP	ECX,[#VY2]
		JLE	#Y2isSmallerThanVY2
		CLIP	[#VY2]
		MOV	[#BX],EAX
		MOV	EBX,[#VY2]
		MOV	[#BY],EBX
		JMP	SHORT #PT2isSettled
		ALIGN	4
#Y2isSmallerThanVY2:
		MOV	[#BX],EDX
		MOV	[#BY],ECX
#PT2isSettled:

		MOV	EAX,[#AX]
		MOV	EBX,[#AY]
		MOV	ECX,[#BX]
		MOV	EDX,[#BY]
		MOV	[#X1],EAX
		MOV	[#Y1],EBX
		MOV	[#X2],ECX
		MOV	[#Y2],EDX


		CMP	ECX,EAX
		JLE	SHORT #VX1isNot1
		MOV	[LVX],1
		JMP	SHORT #VX1isSettled
		ALIGN	4
#VX1isNot1:
		JE	SHORT #VX1is0
		MOV	[LVX],-1
		JMP	SHORT #VX1isSettled
		ALIGN	4
#VX1is0:
		MOV	[LVX],0
#VX1isSettled:


		CMP	EDX,EBX
		JLE	SHORT #VY1isNot1
		MOV	[LVY],YGH_XBUF*4
		JMP	SHORT #VY1isSettled
		ALIGN	4
#VY1isNot1:
		JE	SHORT #VY1is0
		MOV	[LVY],-YGH_XBUF*4
		JMP	SHORT #VY1isSettled
		ALIGN	4
#VY1is0:
		MOV	[LVY],0
#VY1isSettled:


		MOV	EBP,ECX
		MOV	ECX,[LSTVY]
		XOR	ECX,[LVY]
		SETL	CL
		CMP	[LSTVY],DWORD PTR 0
		SETNE	CH
		AND	CL,CH
		CMP	[LVY],DWORD PTR 0
		SETNE	CH
		AND	CL,CH
		MOVZX	ECX,CL
		MOV	[#SP],ECX
		MOV	ECX,EBP


		CMP	[LVY],0
		JE	#LastVYisSettled
		MOV	EBP,[LVY]
		MOV	[LSTVY],EBP
		CMP	[FSTVY],0
		JNE	#LastVYisSettled
		MOV	[FSTVY],EBP
		MOV	[FSTY],EBX
		MOV	EBP,EAX
		CUTX	EBP,[#VX1],[#VX2]
		MOV	[FSTX],EBP
#LastVYisSettled:


		CMP	EAX,[#VX1]
		JGE	#BothIsNotLeft
		CMP	ECX,[#VX1]
		JGE	#BothIsNotLeft

		MOV	EAX,[#VX1]
		CMP	[#SP],DWORD PTR 0
		JE	#BothIsLeft
		MOV	EDI,EBX
		SHL	EDI,YGH_XBUFSHIFT
		LEA	EDI,[ESI+EDI]
		ADDBUF		
#BothIsLeft:	VERTICAL
		JMP	#EXIT
		ALIGN	4
#BothIsNotLeft:

		AND	[DRAWF],DWORD PTR 0FDH

		CMP	EAX,[#VX2]
		JLE	#BothIsNotRight
		CMP	ECX,[#VX2]
		JLE	#BothIsNotRight

		MOV	EAX,[#VX2]
		CMP	[#SP],DWORD PTR 0
		JE	#BothIsRight
		MOV	EDI,EBX
		SHL	EDI,YGH_XBUFSHIFT
		LEA	EDI,[ESI+EDI]
		ADDBUF		
#BothIsRight:	VERTICAL
		JMP	#EXIT
		ALIGN	4
#BothIsNotRight:

		AND	[DRAWF],DWORD PTR 0FBH

		CMP	[LVY],0
		JE	#EXIT


		CMP	[#SP],DWORD PTR 0
		JE	#PT1isFinished
		MOV	EBP,EAX
		CUTX	EAX,[#VX1],[#VX2]
		MOV	EDI,EBX
		SHL	EDI,YGH_XBUFSHIFT
		LEA	EDI,[ESI+EDI]
		ADDBUF
		MOV	EAX,EBP
#PT1isFinished:


		CMP	EAX,ECX
		JNE	#ThisIsNotVertical
		VERTICAL
		JMP	#EXIT
		ALIGN	4


#ThisIsNotVertical:
		CMP	EAX,[#VX1]
		JGE	#PT1isNotLeft
		CLIP	[#VX1]
		MOV	EDX,EAX
		MOV	EAX,[#VX1]
		MOV	EBX,[#Y1]
		MOV	[#X1],EAX
		MOV	[#Y1],EDX
		VERTICAL
		JMP	#PT1isNotRight
		ALIGN	4
#PT1isNotLeft:
		CMP	EAX,[#VX2]
		JLE	#PT1isNotRight
		CLIP	[#VX2]
		MOV	EDX,EAX
		MOV	EAX,[#VX2]
		MOV	EBX,[#Y1]
		MOV	[#X1],EAX
		MOV	[#Y1],EDX
		VERTICAL
#PT1isNotRight:


		MOV	EAX,[#X1]
		MOV	EBX,[#Y1]
		MOV	ECX,[#X2]
		MOV	EDX,[#Y2]

		CMP	ECX,[#VX1]
		JGE	#PT2isNotLeft
		CLIP	[#VX1]
		MOV	ECX,[#VX1]
		MOV	EDX,EAX
		JMP	SHORT #PT2isNotRight
		ALIGN	4
#PT2isNotLeft:
		CMP	ECX,[#VX2]
		JLE	#PT2isNotRight
		CLIP	[#VX2]
		MOV	ECX,[#VX2]
		MOV	EDX,EAX
#PT2isNotRight:


		MOV	EAX,[#X1]
		MOV	EBX,[#Y1]
		POLYGON_NORMAL



		CMP	EDX,[#Y2]
		JE	#EXIT

		MOV	EAX,ECX
		MOV	EBX,EDX
		MOV	EDX,[#Y2]
		VERTICAL


	
#EXIT:		ADD	ESP,#ESPOFS
		POP	EBP
		POP	EDI
		POP	ESI
		RET

		ALIGN	4
#XCHECK:	CMP	EAX,[#VX1]
		SETGE	BL
		CMP	ECX,[#VX1]
		SETGE	BH
		OR	BL,BH
		SHL	BL,1
		AND	[DRAWF],EBX

		CMP	EAX,[#VX2]
		SETLE	DL
		CMP	ECX,[#VX2]
		SETLE	DH
		OR	DL,DH
		SHL	DL,2
		AND	[DRAWF],EDX

		ADD	ESP,#ESPOFS
		POP	EBP
		POP	EDI
		POP	ESI
		RET


POLYGON_LINE	ENDP


;int polygon(int *plg,int *pnt)
;{
;    int drawf,pn;
;    int x1,y1,x2,y2;
;    int xo,yo;              /* 頂点0番の座標 */
;    int i;
;
;    if(*pnt<3)return 0;
;
;    lstvy=0;
;    fstvy=0;
;    drawf=0;
;    mnx=pnt[1];
;    max=pnt[1];
;    mny=pnt[2];
;    may=pnt[2];
;    for(i=0; i<LNG; i++)plg[i*XBUF]=0;
;
;    pn=*pnt-1;
;    xo=pnt[1];
;    yo=pnt[2];
;    x2=pnt[1];
;    y2=pnt[2];
;    pnt+=3;
;
;    while(pn>0)
;    {
;        x1=x2;
;        y1=y2;
;        x2=* pnt;
;        y2=*(pnt+1);
;        drawf |= polygon_line(plg,x1,y1,x2,y2);
;        pnt+=2;
;        pn--;
;    }
;
;    drawf |= polygon_line(plg,x2,y2,xo,yo);
;
;    if(lstvy*fstvy<0)
;    {
;        polygon_addPoint(plg,fstx,fsty);
;    }
;
;    YGB_color(EGB_work,32767-31);
;    YGB_box(EGB_work,xo-4,yo-4,xo+4,yo+4);
;
;    return drawf;
;}

		ALIGN	4
YGH_polygonArea	PROC

#PNT		EQU	EBP+20
#EDG		EQU	EBP+16
#AREA		EQU	EBP+12
#PAGE		EQU	EBP+8
#RETADR		EQU	EBP+4
#EBP		EQU	EBP
#XO		EQU	EBP-4
#YO		EQU	EBP-8
#X2		EQU	EBP-12
#Y2		EQU	EBP-16
#PN		EQU	EBP-20
#ESPOFS		EQU	20

		PUSH	EBP
		MOV	EBP,ESP
		SUB	ESP,#ESPOFS
		PUSH	ESI
		PUSH	EDI
		PUSH	EBX

		MOV	ESI,[#PNT]
		CMP	[ESI],DWORD PTR 3
		JL	#ERROR2

		MOV	EDI,[#PAGE]
		STD

		MOV	[LSTVY],0
		MOV	[FSTVY],0
		MOV	[DRAWF],DWORD PTR 7

		MOV	EAX,[ESI+4]
		MOV	EBX,[ESI+8]
		MOV	[MNX],EAX
		MOV	[MNY],EBX
		MOV	[MAX],EAX
		MOV	[MAY],EBX
		MOV	[#XO],EAX
		MOV	[#YO],EBX
		MOV	[#X2],EAX
		MOV	[#Y2],EBX

		MOV	EDX,[EDI+YGH_VY1]
		SHL	EDX,YGH_XBUFSHIFT
		ADD	EDX,[#AREA]
		MOV	ECX,[EDI+YGH_VY2]
		SUB	ECX,[EDI+YGH_VY1]
		INC	ECX
		MOV	EAX,YGH_XBUF * 4
		SUB	EBX,EBX
#ClearBuffer:	MOV	[EDX],EBX
		ADD	EDX,EAX
		LOOP	#ClearBuffer

		MOV	EAX,[ESI]
		DEC	EAX
		MOV	[#PN],EAX
		ADD	[#PNT],DWORD PTR (3 *4)

		MOV	EDI,[#PAGE]
		MOV	ESI,[#AREA]

#LOOP0:		MOV	EAX,[#X2]
		MOV	EBX,[#Y2]
		MOV	EDX,[#PNT]
		MOV	ECX,[EDX]
		MOV	EDX,[EDX+4]
		MOV	[#X2],ECX
		MOV	[#Y2],EDX

		CALL	POLYGON_LINE

		ADD	[#PNT],DWORD PTR (2 *4)
		DEC	DWORD PTR [#PN]
		JNE	#LOOP0

		MOV	EAX,[#X2]
		MOV	EBX,[#Y2]
		MOV	ECX,[#XO]
		MOV	EDX,[#YO]
		CALL	POLYGON_LINE

		MOV	EAX,[LSTVY]
		XOR	EAX,[FSTVY]
		JGE	#NOADDBUF
		CMP	[LSTVY],DWORD PTR 0
		JE	#NOADDBUF
		CMP	[FSTVY],DWORD PTR 0
		JE	#NOADDBUF

		MOV	EAX,[FSTX]
		MOV	EDI,[FSTY]
		SHL	EDI,YGH_XBUFSHIFT
		LEA	EDI,[EDI+ESI]
		ADDBUF

#NOADDBUF:
		CMP	[DRAWF],DWORD PTR 0
		JNE	#ERROR1

		MOV	EAX,0
#EXIT:		CLD
		MOV	ESI,OFFSET MNX
		MOV	EDI,[#EDG]
		MOV	ECX,4
		REP	MOVSD

		POP	EBX
		POP	EDI
		POP	ESI
		MOV	ESP,EBP
		POP	EBP
		RET

		ALIGN	4
#ERROR1:	MOV	EAX,1
		JMP	#EXIT
		ALIGN	4
#ERROR2:	MOV	EAX,2
		JMP	#EXIT
YGH_polygonArea	ENDP

CODE		ENDS
		END



;どうしてもループ展開が速くならなかった時はこっち

CMPBUF		MACRO	TRANS
		SCASD
		JLE	TRANS
		DEC	ECX
		ENDM

;ADDBUF   EDI:ライン格納バッファ   EAX:追加する値
ADDBUF		MACRO
		LOCAL	JTBL
		LOCAL	L00,L01,L02,L03,L04,L05,L06,L07
		LOCAL	L08,L09,L10,L11,L12,L13,L14
		LOCAL	TRANS
		LOCAL	IGNORE

		PUSH	ECX
		PUSH	ESI
		PUSH	EDI

		MOV	ECX,[EDI]
		INC	DWORD PTR [EDI]
		LEA	EDI,[EDI+4]
		JMP	CS:[JTBL+ECX*4]

		ALIGN	4
JTBL		DD	OFFSET L00,OFFSET L01,OFFSET L02,OFFSET L03
		DD	OFFSET L04,OFFSET L05,OFFSET L06,OFFSET L07
		DD	OFFSET L08,OFFSET L09,OFFSET L10,OFFSET L11
		DD	OFFSET L12,OFFSET L13,OFFSET L14,OFFSET IGNORE

		ALIGN	4
L14:		CMPBUF	TRANS
L13:		CMPBUF	TRANS
L12:		CMPBUF	TRANS
L11:		CMPBUF	TRANS
L10:		CMPBUF	TRANS
L09:		CMPBUF	TRANS
L08:		CMPBUF	TRANS
L07:		CMPBUF	TRANS
L06:		CMPBUF	TRANS
L05:		CMPBUF	TRANS
L04:		CMPBUF	TRANS
L03:		CMPBUF	TRANS
L02:		CMPBUF	TRANS

;L01:		CMPBUF	TRANS
;		JMP	L00
L01:		SCASD
		JG	L00

		ALIGN	4
TRANS:		LEA	EDI,[EDI+ECX*4-4]
		LEA	ESI,[EDI-4]
		STD	
		REP	MOVSD
		CLD

L00:		MOV	[EDI],EAX

IGNORE:		POP	EDI
		POP	ESI
		POP	ECX
		ENDM




;ループ展開のあげくにわけがわからんくなった時のために(^_^;)
POLYGON_NORMAL	MACRO
		LOCAL	qDXisSmallerThanDY
		LOCAL	qXMOV
		LOCAL	qDXisLargerThanDY
		LOCAL	qDXisLargerThanDYloop
		LOCAL	qDXisAsSameAsDY
		LOCAL	qDXisAsSameAsDYloop
		LOCAL	qEXIT

		PUSHAD

		MOV	EDI,EBX
		SHL	EDI,YGH_XBUFSHIFT
		LEA	EDI,[ESI+EDI]		;ESI解放

		SUBABS	ECX,EAX
		SUBABS	EDX,EBX
		JE	qEXIT
		MOV	EBX,ECX		;EBX:a
		MOV	ECX,EDX		;ECX:b
		MOV	EBP,EDX		;EBP:c
		MOV	ESI,0		;ESI:Rf(a==bでは不使用)

		MOV	EDX,[LVY]	;EDX:VY(a>bでは不使用)

		CMP	EBX,ECX
		JG	qDXisLargerThanDY
		JE	qDXisAsSameAsDY

		ALIGN	4
qDXisSmallerThanDY:
		ADD	EDI,EDX
		ADDBUF
		ADD	ESI,EBX
		JG	qXMOV

		DEC	EBP
		JNE	qDXisSmallerThanDY
		JMP	qEXIT
		ALIGN	4
qXMOV:
		ADD	EAX,[LVX]
		SUB	ESI,ECX
		DEC	EBP
		JNE	qDXisSmallerThanDY
		JMP	qEXIT
		ALIGN	4

qDXisLargerThanDY:
qDXisLargerThanDYloop:
		XCHG	EAX,ESI		;TEMP:  EAX=RF  ESI=X
		SUB	EDX,EDX
		IDIV	ECX		;TEMP:  EAX=RF/B  EDX=RF%B
		INC	EAX
		IMUL	EAX,[LVX]
		LEA	EAX,[ESI+EAX]	;EAX=X+(RF/B+1)*VX

		ADD	EDI,[LVY]

		SUB	EDX,ECX
		LEA	ESI,[EDX+EBX]

		ADDBUF

		DEC	EBP
		JNE	qDXisLargerThanDYloop
		JMP	qEXIT
		ALIGN	4


qDXisAsSameAsDY:
		MOV	ESI,[LVX]
		ALIGN	4
qDXisAsSameAsDYloop:
		ADD	EAX,ESI
		ADD	EDI,EDX
		ADDBUF
		DEC	EBP
		JNE	qDXisAsSameAsDYloop

qEXIT:		POPAD
		ENDM

