
;SLINE.INC - Copyright 1991-1994 Knight Software
;    History:
;        17 May 1991 - first release
;        22 Nov 1992 - adapted for protected mode operation
;	 25 Nov 1994 - improved line draw algorithm 
;
;--------------------------------------------------
;put a pixel on the screen in the indicated color for line type 
;drawing. Assumes that the address and segment have been preset
;Assume: DS = data segment
;Entry:  AL=0:x dominant line, AL=1:y dominant line
;Return: N/A
DrawLinePixel PROC NEAR
	PUSH	ES
	PUSH	DI
	PUSH	CX
	PUSH	BX
	PUSH	AX
	MOV	DI,DS:[PixelAddress]  ;get the address to write
	MOV	ES,DS:[VideoSegment]  ;video is at segment 0a000h
	CMP	BYTE PTR DS:[LineStyleMode],2 ;if type 2, use
	JC	@DLPixelA		      ;fixed pattern
	MOV	CL,BYTE PTR DS:[PixelX]
	OR	AL,AL
	JZ	@DLPixelB
	MOV	CL,BYTE PTR DS:[PixelY]
	JMP	SHORT @DLPixelB
@DLPixelA:
	MOV	CL,DS:[LinePixelCount]	      ;else use pixel count
	INC	BYTE PTR DS:[LinePixelCount]
@DLPixelB:
	AND	CL,0FH
	MOV	BX,DS:[LinePattern]
	SHR	BX,CL
	MOV	AL,DS:[DrawForeColor] ;Get foreground color to plot
	MOV	AH,DS:[DrawBackColor] ;Get background color to plot
	AND	BL,01H		      ;set zero flag for call
	CALL	WORD PTR DS:[LinePixelProc] ;write to video memory
	POP	AX
	POP	BX
	POP	CX
	POP	DI
	POP	ES
	RET
DrawLinePixel ENDP

;-----------------------------------------------------
;line drawing procedure - draw a line from x1,y1 to x2,y2
;Assume: DS = data segment
;Entry:  AX = X1  start coordinate
; 	 BX = Y1  start coordinate
;	 CX = X2  end coordinate
;	 DX = Y2  end coordinate
;Return: N/A

PlotLine PROC NEAR
	PUSH	AX
	PUSH	BX
	PUSH	CX
	PUSH	DX
	PUSH	SI
	PUSH	DI
	MOV	DS:[PixelX],AX	; save x1
	MOV	DS:[PixelX2],CX	; save x2
	MOV	DS:[PixelY],BX	; save y1
	MOV	DS:[PixelY2],DX	; save y2
	CMP	BYTE PTR DS:[LineStyleMode],0
	JNZ	@DrawB		; if std style, clr pattern count
	MOV	BYTE PTR DS:[LinePixelCount],0

@DrawB:	MOV	SI,1
	SUB	CX,AX	;AX=DeltaX = abs(x2 - x1)*2
	JNS	@DrawC	;if x2>=x1 then Xinc=1 else Xinc=-1
	NEG	CX
	NEG	SI	;SI=Xinc
@DrawC:	ADD	CX,CX
	MOV	DI,1
	SUB	DX,BX	;DX=DeltaY = abs(y2 - y1)*2
	JNS	@DrawD	;if y2>=y1 then Yinc=1 else Yinc=-1
	NEG	DX
	NEG	DI	;DI=Yinc
@DrawD:	ADD	DX,DX

	CMP	CX,DX   ;1,0=NC  1,1=NC  0,1=C
	JG	@DrawX	;if DeltaX > DeltaY then X is dominant
	JMP	@DrawY

;do X dominant line draw
@DrawX:	MOV	AX,CX	;Dir = AY - (AX / 2)
	SHR	AX,1
	MOV	BX,DX
	SUB	BX,AX
@LoopX:	CALL	GetPixelAddress ; plot pixel
	MOV	AL,0		;0=x dominant line 
	CALL	DrawLinePixel	; plot x,y,color
	MOV	AX,DS:[PixelX2]	;if x1 >= x2 exit
	CMP	AX,DS:[PixelX]
	JZ	@Plexit
	OR	BX,BX
	JS	@Draw3
	ADD	DS:[PixelY],DI
	SUB	BX,CX
@Draw3:	ADD	DS:[PixelX],SI
	ADD	BX,DX
	JMP	@LoopX

;do Y dominant line draw
@DrawY:	MOV	AX,DX	;Dir = AX - (AY / 2)
	SHR	AX,1
	MOV	BX,CX
	SUB	BX,AX
@LoopY:	CALL	GetPixelAddress ; plot pixel
	MOV	AL,1		;1=y dominant line 
	CALL	DrawLinePixel	; plot x,y,color
	MOV	AX,DS:[PixelY2]	;if y1 >= y2 exit
	CMP	AX,DS:[PixelY]
	JZ	@Plexit
	OR	BX,BX
	JS	@Draw4
	ADD	DS:[PixelX],SI
	SUB	BX,DX
@Draw4:	ADD	DS:[PixelY],DI
	ADD	BX,CX
	JMP	@LoopY

@Plexit:
	POP	DI
	POP	SI
	POP	DX
	POP	CX
	POP	BX
	POP	AX
	RET

PlotLine ENDP


