		.386p
		ASSUME	CS:CODE

		INCLUDE YGHASM.H

		PUBLIC	YGH_line,YGH_lineClip
		PUBLIC	YGH_connect,YGH_unConnect,YGH_emptyPolygon


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




CODE		SEGMENT

		ALIGN	4
YGH_line	PROC
#Y2		EQU	ESP+36
#X2		EQU	ESP+32
#Y1		EQU	ESP+28
#X1		EQU	ESP+24
#PAGE		EQU	ESP+20
#RETADR		EQU	ESP+16
#EBP		EQU	ESP+12
#ESI		EQU	ESP+8
#EDI		EQU	ESP+4
#EBX		EQU	ESP

		PUSH	EBP
		PUSH	ESI
		PUSH	EDI
		PUSH	EBX

		MOV	EAX,[#X1]
		MOV	EBX,[#Y1]
		MOV	ECX,[#X2]
		MOV	EDX,[#Y2]
		MOV	EDI,[#PAGE]
		CALL	LINECLIP
		JC	#EXIT

		CALL	LINEDRAW

#EXIT:		POP	EBX
		POP	EDI
		POP	ESI
		POP	EBP
		MOV	EAX,0
		RET
YGH_line	ENDP




		ALIGN	4
YGH_connect	PROC
#POINTS		EQU	ESP+28
#PAGE		EQU	ESP+24
#RETADR		EQU	ESP+20
#EBP		EQU	ESP+16
#ESI		EQU	ESP+12
#EDI		EQU	ESP+8
#EBX		EQU	ESP+4
#ESPOFS		EQU	4
#NPOINT		EQU	ESP

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

		MOV	EDI,[#PAGE]
		MOV	ESI,[#POINTS]
		LODSD
		CMP	EAX,2
		JL	#EXIT
		DEC	EAX
		MOV	[#NPOINT],EAX

#LOOP0:		MOV	EAX,[ESI]
		MOV	EBX,[ESI+4]
		MOV	ECX,[ESI+8]
		MOV	EDX,[ESI+12]
		MOV	EDI,[#PAGE]
		CALL	LINECLIP
		JC	#NEXT
		PUSH	ESI
		CALL	LINEDRAW
		POP	ESI
#NEXT:		LEA	ESI,[ESI+8]
		DEC	DWORD PTR [#NPOINT]
		JNE	#LOOP0

#EXIT:		ADD	ESP,#ESPOFS
		POP	EBX
		POP	EDI
		POP	ESI
		POP	EBP
		MOV	EAX,0
		RET
YGH_connect	ENDP



		ALIGN	4
YGH_unConnect	PROC
#POINTS		EQU	ESP+28
#PAGE		EQU	ESP+24
#RETADR		EQU	ESP+20
#EBP		EQU	ESP+16
#ESI		EQU	ESP+12
#EDI		EQU	ESP+8
#EBX		EQU	ESP+4
#ESPOFS		EQU	4
#NPOINT		EQU	ESP

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

		MOV	EDI,[#PAGE]
		MOV	ESI,[#POINTS]
		LODSD
		CMP	EAX,2
		JL	#EXIT
		SHR	EAX,1
		MOV	[#NPOINT],EAX

#LOOP0:		MOV	EAX,[ESI]
		MOV	EBX,[ESI+4]
		MOV	ECX,[ESI+8]
		MOV	EDX,[ESI+12]
		MOV	EDI,[#PAGE]
		CALL	LINECLIP
		JC	#NEXT
		PUSH	ESI
		CALL	LINEDRAW
		POP	ESI
#NEXT:		LEA	ESI,[ESI+16]
		DEC	DWORD PTR [#NPOINT]
		JNE	#LOOP0

#EXIT:		ADD	ESP,#ESPOFS
		POP	EBX
		POP	EDI
		POP	ESI
		POP	EBP
		MOV	EAX,0
		RET
YGH_unConnect	ENDP



		ALIGN	4
YGH_emptyPolygon	PROC
#POINTS		EQU	ESP+36
#PAGE		EQU	ESP+32
#RETADR		EQU	ESP+28
#EBP		EQU	ESP+24
#ESI		EQU	ESP+20
#EDI		EQU	ESP+16
#EBX		EQU	ESP+12
#ESPOFS		EQU	12
#NPOINT		EQU	ESP+8
#FSTX		EQU	ESP+4
#FSTY		EQU	ESP

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

		MOV	EDI,[#PAGE]
		MOV	ESI,[#POINTS]
		LODSD
		CMP	EAX,2
		JL	#EXIT
		DEC	EAX
		MOV	[#NPOINT],EAX

		MOV	EAX,[ESI]
		MOV	EBX,[ESI+4]
		MOV	[#FSTX],EAX
		MOV	[#FSTY],EBX

#LOOP0:		MOV	EAX,[ESI]
		MOV	EBX,[ESI+4]
		MOV	ECX,[ESI+8]
		MOV	EDX,[ESI+12]
		MOV	EDI,[#PAGE]
		CALL	LINECLIP
		JC	#NEXT
		PUSH	ESI
		CALL	LINEDRAW
		POP	ESI
#NEXT:		LEA	ESI,[ESI+8]
		DEC	DWORD PTR [#NPOINT]
		JNE	#LOOP0

		MOV	EAX,[ESI]
		MOV	EBX,[ESI+4]
		MOV	ECX,[#FSTX]
		MOV	EDX,[#FSTY]
		MOV	EDI,[#PAGE]
		CALL	LINECLIP
		JC	#EXIT
		CALL	LINEDRAW

#EXIT:		ADD	ESP,#ESPOFS
		POP	EBX
		POP	EDI
		POP	ESI
		POP	EBP
		MOV	EAX,0
		RET
YGH_emptyPolygon	ENDP


;LINEDRAW
;EAX,EBX,ECX,EDX:X1,Y1,X2,Y2     EDI:PAGE
; X1,Y1,X2,Y2 should be already clipped
		ALIGN	4
LINEDRAW	PROC
#VY		EQU	ESP+24
#VX		EQU	ESP+20
#DB		EQU	ESP+16
#DA		EQU	ESP+12
#P2ADR		EQU	ESP+8
#P1ADR		EQU	ESP+4
#RF		EQU	ESP
#ESPOFS		EQU	28

		PUSH	DS
		PUSH	ES
		SUB	ESP,#ESPOFS

		PUSH	DS
		POP	ES
		MOV	ESI,[EDI+YGH_SEG]
		MOV	DS,SI

		MOV	DWORD PTR [#RF],0

		MOV	ESI,EBX
		IMUL	ESI,ES:[EDI+YGH_ODW]
		LEA	ESI,[ESI+EAX*2]
		ADD	ESI,ES:[EDI+YGH_ADR]
		MOV	[#P1ADR],ESI

		MOV	ESI,EDX
		IMUL	ESI,ES:[EDI+YGH_ODW]
		LEA	ESI,[ESI+ECX*2]
		ADD	ESI,ES:[EDI+YGH_ADR]
		MOV	[#P2ADR],ESI



		MOV	DWORD PTR [#VX],2  ; X 1dot -> 2bytes
		MOV	[#DA],ECX
		SUB	[#DA],EAX
		JE	#VERTICAL
		JG	#X2LARGE
		NEG	DWORD PTR [#VX]
		NEG	DWORD PTR [#DA]
#X2LARGE:

		MOV	ESI,ES:[EDI+YGH_ODW]
		MOV	[#VY],ESI
		MOV	[#DB],EDX
		SUB	[#DB],EBX
		JE	#HORIZONTAL
		JG	#Y2LARGE
		NEG	DWORD PTR [#VY]
		NEG	DWORD PTR [#DB]
#Y2LARGE:



; DA>DB / DA<DB で場合分け
		MOV	EAX,[#P1ADR]
		MOV	EBX,ES:[EDI+YGH_COL]
		MOV	[EAX],BX

		MOV	ESI,[#DA]
		MOV	EDI,[#DB]
		CMP	ESI,EDI
		JL	#STEEP

		MOV	ECX,[#DA]
		MOV	EDX,[#RF]
		MOV	ESI,[#VX]

		ALIGN	4
#LOOP1:		ADD	EAX,ESI
		SUB	EDX,EDI
		JL	#YMOV
		MOV	[EAX],BX
		LOOP	#LOOP1
		JMP	#EXIT
		ALIGN	4
#YMOV:		ADD	EAX,[#VY]
		MOV	[EAX],BX
		ADD	EDX,[#DA]
		LOOP	#LOOP1

		ADD	ESP,#ESPOFS
		POP	ES
		POP	DS
		RET

		ALIGN	4
#STEEP:		MOV	ECX,[#DB]
		MOV	EDX,[#RF]
		MOV	EDI,[#VY]

		ALIGN	4
#LOOP2:		ADD	EAX,EDI
		ADD	EDX,ESI
		JG	#XMOV
		MOV	[EAX],BX
		LOOP	#LOOP2
		JMP	#EXIT
		ALIGN	4
#XMOV:		ADD	EAX,[#VX]
		MOV	[EAX],BX
		SUB	EDX,[#DB]
		LOOP	#LOOP2	

		ADD	ESP,#ESPOFS
		POP	ES
		POP	DS
		RET


		ALIGN	4
;垂直直線
#VERT_JTBL	DD	OFFSET #V0,OFFSET #V1,OFFSET #V2,OFFSET #V3
		DD	OFFSET #V4,OFFSET #V5,OFFSET #V6,OFFSET #V7
#VERTICAL:
		MOV	ECX,ES:[EDI+YGH_COL]
		MOV	EAX,[#P1ADR]
		MOV	[EAX],CX

		SUB	EDX,EBX
		JE	#EXIT
		JG	#VT_Y2LARGE
		NEG	EDX
		MOV	EAX,[#P2ADR]
#VT_Y2LARGE:
		MOV	EDI,ES:[EDI+YGH_ODW]
		MOV	ESI,EDX
		AND	ESI,7
		JMP	CS:[#VERT_JTBL + ESI*4]

		ALIGN	4
#V0:		ADD	EAX,EDI
		MOV	[EAX],CX
#V7:		ADD	EAX,EDI
		MOV	[EAX],CX
#V6:		ADD	EAX,EDI
		MOV	[EAX],CX
#V5:		ADD	EAX,EDI
		MOV	[EAX],CX
#V4:		ADD	EAX,EDI
		MOV	[EAX],CX
#V3:		ADD	EAX,EDI
		MOV	[EAX],CX
#V2:		ADD	EAX,EDI
		MOV	[EAX],CX
#V1:		ADD	EAX,EDI
		MOV	[EAX],CX
		SUB	EDX,8
		JG	#V0

		ADD	ESP,#ESPOFS
		POP	ES
		POP	DS
		RET

;水平直線
		ALIGN	4
#HORIZONTAL:
		MOV	ESI,ES:[EDI+YGH_COL]
		MOV	EDI,[#P1ADR]
		MOV	ECX,[#P2ADR]
		MOV	[EDI],SI
		MOV	[ECX],SI

		CMP	EDI,ECX
		JE	#EXIT
		JL	#HOR_X1SMALL
		XCHG	EDI,ECX
#HOR_X1SMALL:

		ADD	EDI,2
		AND	EDI,0FFFFFFFFH -3

		SUB	ECX,EDI
		ADD	ECX,2
		SHR	ECX,2

		MOVZX	EAX,SI
		SHL	ESI,16
		OR	EAX,ESI
		PUSH	DS
		POP	ES
		REP	STOSD

#EXIT:		ADD	ESP,#ESPOFS
		POP	ES
		POP	DS
		RET

LINEDRAW	ENDP






		ALIGN	4
YGH_lineClip	PROC
#Y2PTR		EQU	ESP+28
#X2PTR		EQU	ESP+24
#Y1PTR		EQU	ESP+20
#X1PTR		EQU	ESP+16
#PAGE		EQU	ESP+12
#RETADR		EQU	ESP+8
#EBX		EQU	ESP+4
#EDI		EQU	ESP

		PUSH	EBX
		PUSH	EDI

		MOV	EAX,[#X1PTR]
		MOV	EAX,[EAX]
		MOV	EBX,[#Y1PTR]
		MOV	EBX,[EBX]
		MOV	ECX,[#X2PTR]
		MOV	ECX,[ECX]
		MOV	EDX,[#Y2PTR]
		MOV	EDX,[EDX]
		MOV	EDI,[#PAGE]
		CALL	LINECLIP
		JC	#OUT

		MOV	EDI,[#X1PTR]
		MOV	[EDI],EAX
		MOV	EDI,[#Y1PTR]
		MOV	[EDI],EBX
		MOV	EDI,[#X2PTR]
		MOV	[EDI],ECX
		MOV	EDI,[#Y2PTR]
		MOV	[EDI],EDX

		POP	EDI
		POP	EBX
		MOV	EAX,0
		RET

#OUT:		POP	EDI
		POP	EBX
		MOV	EAX,1
		RET
YGH_lineClip	ENDP



;  EAX,EBX,ECX,EDX:X1,Y1,X2,Y2    EDI:PAGE
		ALIGN	4
LINECLIP	PROC
#Y2		EQU	ESP+12
#X2		EQU	ESP+8
#Y1		EQU	ESP+4
#X1		EQU	ESP
#ESPOFS		EQU	16

		PUSH	ESI
		SUB	ESP,#ESPOFS
		SUB	ESI,ESI		;ESI:XCHG FLAG

;垂直直線?
		CMP	EAX,ECX
		JE	#VERTICAL
;水平直線?
		CMP	EBX,EDX
		JE	#HORIZONTAL


; X1>X2 の時は、入れ換える
		CMP	EAX,ECX
		JL	#X2BIGGER
		XCHG	EAX,ECX
		XCHG	EBX,EDX
		INC	ESI
#X2BIGGER:


; 明らかに画面外の場合は抜ける
		CMP	EAX,[EDI+YGH_VX2]
		JG	#OUT
		CMP	ECX,[EDI+YGH_VX1]
		JL	#OUT


; 入れ換えた物を一旦バッファに
		MOV	[#X1],EAX
		MOV	[#Y1],EBX
		MOV	[#X2],ECX
		MOV	[#Y2],EDX

; 画面左のクリップ
		CMP	EAX,[EDI+YGH_VX1]
		JGE	#NOLEFTCLIP
		CLIP	[EDI+YGH_VX1]
		CMP	EAX,[EDI+YGH_VY1]
		JL	#NOLEFTCLIP
		CMP	EAX,[EDI+YGH_VY2]
		JG	#NOLEFTCLIP
		MOV	[#Y1],EAX
		MOV	EAX,[EDI+YGH_VX1]
		MOV	[#X1],EAX
#NOLEFTCLIP:	MOV	EAX,[#X1]
		MOV	EBX,[#Y1]
		MOV	ECX,[#X2]
		MOV	EDX,[#Y2]

; 画面右のクリップ
		CMP	ECX,[EDI+YGH_VX2]
		JLE	#NORIGHTCLIP
		CLIP	[EDI+YGH_VX2]
		CMP	EAX,[EDI+YGH_VY1]
		JL	#NORIGHTCLIP
		CMP	EAX,[EDI+YGH_VY2]
		JG	#NORIGHTCLIP
		MOV	[#Y2],EAX
		MOV	EAX,[EDI+YGH_VX2]
		MOV	[#X2],EAX
#NORIGHTCLIP:

; 次は Y についてだから EAX,EBX,ECX,EDX は Y1,X1,Y2,X2
		MOV	EAX,[#Y1]
		MOV	EBX,[#X1]
		MOV	ECX,[#Y2]
		MOV	EDX,[#X2]


; Y1>Y2 なら入れ換える
		CMP	EAX,ECX
		JL	#Y2BIGGER
		XCHG	EAX,ECX
		XCHG	EBX,EDX
		INC	ESI
#Y2BIGGER:

; 明らかに画面外なら抜ける
		CMP	ECX,[EDI+YGH_VY1]
		JL	#OUT
		CMP	EAX,[EDI+YGH_VY2]
		JG	#OUT

; 入れ換えた物を一旦バッファに
		MOV	[#Y1],EAX
		MOV	[#X1],EBX
		MOV	[#Y2],ECX
		MOV	[#X2],EDX

; 上の辺のクリップ
		CMP	EAX,[EDI+YGH_VY1]
		JGE	#NOTOPCLIP
		CLIP	[EDI+YGH_VY1]
		CMP	EAX,[EDI+YGH_VX1]
		JL	#OUT
		CMP	EAX,[EDI+YGH_VX2]
		JG	#OUT
		MOV	[#X1],EAX
		MOV	EAX,[EDI+YGH_VY1]
		MOV	[#Y1],EAX
#NOTOPCLIP:	MOV	EAX,[#Y1]
		MOV	EBX,[#X1]
		MOV	ECX,[#Y2]
		MOV	EDX,[#X2]

;下の辺のクリップ
		CMP	ECX,[EDI+YGH_VY2]
		JLE	#NOBOTTOMCLIP
		CLIP	[EDI+YGH_VY2]
		CMP	EAX,[EDI+YGH_VX1]
		JL	#OUT
		CMP	EAX,[EDI+YGH_VX2]
		JG	#OUT
		MOV	[#X2],EAX
		MOV	EAX,[EDI+YGH_VY2]
		MOV	[#Y2],EAX
#NOBOTTOMCLIP:	MOV	EAX,[#X1]
		MOV	EBX,[#Y1]
		MOV	ECX,[#X2]
		MOV	EDX,[#Y2]

		AND	ESI,1
		JE	#EXIT
		XCHG	EAX,ECX
		XCHG	EBX,EDX

#EXIT:		ADD	ESP,#ESPOFS
		POP	ESI
		CLC
		RET





#VERTICAL:	CMP	EBX,EDX
		JL	#VERT_Y2BIGGER
		XCHG	EBX,EDX
		INC	ESI
#VERT_Y2BIGGER:

; 明らかに画面外の場合は抜ける
		CMP	EAX,[EDI+YGH_VX1]
		JL	#OUT
		CMP	EAX,[EDI+YGH_VX2]
		JG	#OUT
		CMP	EDX,[EDI+YGH_VY1]
		JL	#OUT
		CMP	EBX,[EDI+YGH_VY2]
		JG	#OUT

; 上の辺のクリップ
		CMP	EBX,[EDI+YGH_VY1]
		JGE	#VERT_NOTOPCLIP
		MOV	EBX,[EDI+YGH_VY1]
#VERT_NOTOPCLIP:

;下の辺のクリップ
		CMP	EDX,[EDI+YGH_VY2]
		JLE	#VERT_NOBTMCLIP
		MOV	EDX,[EDI+YGH_VY2]
#VERT_NOBTMCLIP:

		AND	ESI,1
		JE	#EXIT
		XCHG	EBX,EDX

#VERT_EXIT:	ADD	ESP,#ESPOFS
		POP	ESI
		CLC
		RET




#HORIZONTAL:
		CMP	EAX,ECX
		JLE	#HOR_X2BIGGER
		XCHG	EAX,ECX
		INC	ESI
#HOR_X2BIGGER:

; 明らかに画面外の場合は抜ける
		CMP	EBX,[EDI+YGH_VY1]
		JL	#OUT
		CMP	EBX,[EDI+YGH_VY2]
		JG	#OUT
		CMP	ECX,[EDI+YGH_VX1]
		JL	#OUT
		CMP	EAX,[EDI+YGH_VX2]
		JG	#OUT

; 左の辺のクリップ
		CMP	EAX,[EDI+YGH_VX1]
		JGE	#HOR_NOLEFTCLIP
		MOV	EAX,[EDI+YGH_VX1]
#HOR_NOLEFTCLIP:

; 右の辺のクリップ
		CMP	ECX,[EDI+YGH_VX2]
		JLE	#HOR_NORIGHTCLIP
		MOV	ECX,[EDI+YGH_VX2]
#HOR_NORIGHTCLIP:

		AND	ESI,1
		JE	#HOR_EXIT
		XCHG	EAX,ECX

#HOR_EXIT:	ADD	ESP,#ESPOFS
		POP	ESI
		CLC
		RET




#OUT:		ADD	ESP,#ESPOFS
		POP	ESI
		STC
		RET
LINECLIP	ENDP

CODE		ENDS
			END
