;	私製ライブラリ・グラフィック篇
;	(c) MATSUUCHI Ryosuke in Dec,1992
;
;	gline.asm
;
;	1992. 8. 2(Sun)
;	1992.12.28(Sun)

		public	gline,_gline
		extrn	_gwrtreg:near, _gpset:near
		extrn	_ghline:near, _gvline:near
		
		include	grplib.inc
		
		assume	cs:cseg, ds:dseg


POSIT		struc
	x	dd	0
	y	dd	0
POSIT		ends


setPOS		macro	var,xreg,yreg
		mov	[var.x],xreg
		mov	[var.y],yreg
		endm

incPOSx		macro	var
		inc	[var.x]
		endm

decPOSx		macro	var
		dec	[var.x]
		endm

incPOSy		macro	var		;eax を壊す
		mov	eax,[ydir]
		add	[var.y],eax
		endm

decPOSy		macro	var		;eax を壊す
		mov	eax,[ydir]
		sub	[var.y],eax
		endm

psetPOS		macro	var
		local	norm
		pushad
		mov	eax,[var.x]
		mov	ebx,[var.y]
		mov	ecx,[color]
		mov	edx,[logop]
		cmp	[linetype],1
		jnz	norm
		xchg	eax,ebx
norm:		call	_gpset
		popad
		endm



dseg segment dword 'DATA'


x1		dd	0
y1		dd	0
x2		dd	0
y2		dd	0
xlen		dd	0
ylen		dd	0
ydir		dd	0
p1		POSIT	<>
p2		POSIT	<>
rate		dd	0
rateacc		dd	0
ct		dd	0
color		dd	0
logop		dd	0
linetype	dd	0	;0=[xlen > ylen]  1=[xlen < ylen]  2=[xlen = ylen]
				;3=[xlen = 0 ]  4=[ylen = 0 ]


dseg ends



cseg segment dword 'CODE'

;---------------------------------------------------------------
;	_gline : 直線の描画
;		in  EAX : x1
;		    EBX : y1
;		    ECX : x2
;		    EDX : y2
;		    ESI : color
;		    EDI : logop
;
;	void gline(int x1,int y1,int x2,int y2,int col,int logop);
;---------------------------------------------------------------

gline		proc near
		push	ebx
		push	esi
		push	edi
		pushfd
		mov	eax,[esp+16+4]
		mov	ebx,[esp+16+8]
		mov	ecx,[esp+16+12]
		mov	edx,[esp+16+16]
		mov	esi,[esp+16+20]
		mov	edi,[esp+16+24]
		call	_gline
		popfd
		pop	edi
		pop	esi
		pop	ebx
		ret
gline		endp



_gline		proc near
		call	_gline_init
		cmp	[linetype],3
		jl	#6
			call	_gline_hv
			jmp	#7
		#6:
			pushad
			xor	ecx,ecx
			#0:
				cmp	ecx,[ct]
				jnl	#1
				psetPOS	p1
				;psetPOS p2
				cmp	[linetype],2
				jge	#3
					mov	eax,[rate]
					add	[rateacc],eax
					jnc	#2
						incPOSy	p1
						;decPOSy p2
					#2:
					jmp	#4
				#3:
					incPOSy	p1
					;decPOSy p2
				#4:
				inc	ecx
				incPOSx	p1
				;decPOSx p2
			jmp	#0
			#1:
			;bt	[xlen],0
			;jnc	#5
			;	psetPOS	p1
			;#5:
			popad
		#7:
		ret
_gline		endp


;● LINE のサブルーチン（各変数をパラメーターから算出する）
;----------------------------------------------------------------------------


_gline_init	proc
		pushad
		mov	[color],esi
		mov	[logop],edi
		mov	esi,ecx		;esi := abs(x2-x1)
		sub	esi,eax
		jnc	#0
		neg	esi
#0:		mov	edi,edx		;edi := abs(y2-y1)
		sub	edi,ebx
		jnc	#1
		neg	edi
#1:		cmp	esi,0
		je	#9
		cmp	edi,0
		je	#10
		cmp	esi,edi		;abs(x2-x1) と abs(y2-y1) を比較する
		je	#2
		jg	#3
		jmp	#11
		#9:	;-------------[xlen = 0]
			mov	[linetype],3
			jmp	#4
		#10:	;-------------[ylen = 0]
			mov	[linetype],4
			jmp	#4
		#11:	;-------------[xlen < ylen]
			mov	[linetype],1
			xchg	esi,edi
			xchg	eax,ebx
			xchg	ecx,edx
			jmp	#4
		#2:	;-------------[xlen = ylen]
			mov	[linetype],2
			jmp	#4
		#3:	;-------------[xlen > ylen]
			mov	[linetype],0
		#4:
		cmp	eax,ecx		;長辺側の座標を小･大の順にする
		jng	#6
			xchg	eax,ecx
			xchg	ebx,edx
		#6:
		mov	[ydir],1	;短辺側座標の増分を決める
		cmp	ebx,edx
		jng	#7
			mov	[ydir],-1
		#7:
		inc	esi		;長辺のドット数
		mov	[xlen],esi
		inc	edi		;短辺のドット数
		mov	[ylen],edi
		setPOS	p1,eax,ebx	;始点の位置情報
		setPOS	p2,ecx,edx	;終点の位置情報
		cmp	[linetype],2
		jge	#8
			mov	edx,edi		;傾き(短辺 / 長辺)の算出
			xor	eax,eax
			mov	ebx,esi
			div	ebx
			mov	[rate],eax
		#8:
		mov	[ct],esi	;ct := xlen
		mov	[rateacc],0	;傾き加算値の初期化
		popad
		ret
_gline_init	endp


;● LINE のサブルーチン（水平／垂直線の場合）
;----------------------------------------------------------------------------


_gline_hv	proc
		pushad
		cmp	[linetype],3
		jnz	#0
			mov	ecx,edx
			mov	edx,esi
			mov	esi,edi
			call	_gvline
			jmp	#1
		#0:
			xchg	ebx,ecx
			mov	edx,esi
			mov	esi,edi
			call	_ghline
		#1:
		popad
		ret
_gline_hv	endp


cseg ends

end
