OPT	NOEXE,OPTIMIZE

MODULE	'lib/chunky'

OBJECT xy
	x/y:F

OBJECT chunky
	wi/he:L,
	data:PTR TO UBYTE

PROC DrawTriangle(dest:PTR TO chunky,dc:PTR TO xy,c)
	DEFL	y
	DEFF	lx,dlx,rx,drx		// coords on destination chunky
	DEFF	x0,x1,x2,y0,y1,y2,list:PTR TO xy

	list:=[dc[0].x,dc[0].y,dc[1].x,dc[1].y,dc[2].x,dc[2].y]:xy

	DEF	ch,n
	REPEAT
		ch:=FALSE
		FOR n:=0 TO 1
			IF list[n].y>list[n+1].y
				list[n].x:=:list[n+1].x
				list[n].y:=:list[n+1].y
				ch:=TRUE
			ENDIF
		ENDFOR
	UNTIL ch=FALSE

	x0:=list[0].x
	y0:=list[0].y
	x1:=list[1].x
	y1:=list[1].y
	x2:=list[2].x
	y2:=list[2].y

	IF y0=y1 AND x0>x1 THEN x0:=:x1
	IF y1=y2 AND x1>x2 THEN x1:=:x2

	IF y0<0 AND y1<0 AND y2<0 THEN RETURN
	IF x0<0 AND x1<0 AND x2<0 THEN RETURN
	IF y0>=dest.he AND y1>=dest.he AND y2>=dest.he THEN RETURN
	IF x0>=dest.wi AND x1>=dest.wi AND x2>=dest.wi THEN RETURN

	IF y0=y1
// +-------+
//  \     /
//   \   /
//    \ /
//     +
		// initialize coords (and deltas) for destination chunky

		lx:=x0				// first point x
		rx:=x1				// second point x
		dlx:=(x2-lx)/(y2-y0)	// left side delta
		drx:=(x2-rx)/(y2-y0)	// right side delta

		FOR y:=y0 TO y2
			IF y>=dest.he THEN RETURN
			IF y>=0 THEN HLine(dest,lx,rx,y,c)
			lx+=dlx
			rx+=drx
		ENDFOR

//		Triangle1(dest,y0,y2,x0,x1,x2,c)
	ELSEIF y1=y2
//     +
//    / \
//   /   \
//  /     \
// +-------+
		// initialize coords (and deltas) for destination chunky
		lx:=rx:=x0			// first point
		dlx:=(x1-lx)/(y2-y0)	// left side delta
		drx:=(x2-rx)/(y2-y0)	// right side delta

		FOR y:=y0 TO y1-1
			IF y>=dest.he THEN RETURN
			IF y>=0 THEN HLine(dest,lx,rx,y,c)
			lx+=dlx
			rx+=drx
		ENDFOR

	ELSEIF GetXLine(y0,y2,y1,x0,x2)>x1
//    +            +
//   / \          /|
//  /   \        / |
// +_    \      +  |
//   --__ \      \ |
//       --+      \+
		// central point on the left side

		// initialize coords (and deltas) for destination chunky
		lx:=rx:=x0			// first point
		dlx:=(x1-lx)/(y1-y0)	// left side delta
		drx:=(x2-rx)/(y2-y0)	// right side delta

		FOR y:=y0 TO y1-1
			IF y>=dest.he THEN RETURN
			IF y>=0 THEN HLine(dest,lx,rx,y,c)
			lx+=dlx
			rx+=drx
		ENDFOR

		dlx:=(x2-lx)/(y2-y1)	// new left side delta
		FOR y:=y1 TO y2-1
			IF y>=dest.he THEN RETURN
			IF y>=0 THEN HLine(dest,lx,rx,y,c)
			lx+=dlx
			rx+=drx
		ENDFOR
	ELSE
//     +            +
//    / \          /|
//   /   \        / |
//  /     \      +  |
// / ___---+      \ |
//+--              \+
		// central point on the right side

		// initialize coords (and deltas) for destination chunky
		lx:=rx:=x0			// first point
		dlx:=(x2-lx)/(y2-y0)	// left side delta
		drx:=(x1-rx)/(y1-y0)	// right side delta

		FOR y:=y0 TO y1-1
			IF y>=dest.he THEN RETURN
			IF y>=0 THEN HLine(dest,lx,rx,y,c)
			lx+=dlx
			rx+=drx
		ENDFOR

		drx:=(x2-rx)/(y2-y1)	// new right side delta

		FOR y:=y1 TO y2-1
			IF y>=dest.he THEN RETURN
			IF y>=0 THEN HLine(dest,lx,rx,y,c)
			lx+=dlx
			rx+=drx
		ENDFOR
	ENDIF
ENDPROC

PROC GetXLine(y1:F,y2:F,y3:F,x1:F,x2:F)(F) IS
	(x1-x2)*(y2-y3)/(y2-y1)+x2
