'
' NeoLib - Drawing Primitives Module
'
' Features:
'  16 subs
'  1 function
' For a total of: 17 routines
'
' Specially designed and coded for AAP's QBCPC
' Official Library of the QuickBASIC Caliber Programming Compo (Summer & Autumn 2003)
'
DECLARE FUNCTION neoDrawPoint% (Layer AS INTEGER, fromX AS INTEGER, fromY AS INTEGER)

DECLARE SUB neoDrawInitLayers ()
DECLARE SUB neoDrawSetClipBox (X1 AS INTEGER, Y1 AS INTEGER, X2 AS INTEGER, Y2 AS INTEGER)
DECLARE SUB neoDrawPixel (Layer AS INTEGER, toX AS INTEGER, toY AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawLine (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawLineGouraud (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, StartCol AS INTEGER, EndCol AS INTEGER)
DECLARE SUB neoDrawBox (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawBoxF (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawBoxTrans (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER, StdPal AS STRING, Neg AS INTEGER)
DECLARE SUB neoDrawCircle (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, Radius AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawCircleF (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, Radius AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawEllipse (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, XRadius AS INTEGER, YRadius AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawEllipseF (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, XRadius AS INTEGER, YRadius AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawPolygon (Layer AS INTEGER, PolyArray() AS ANY, Colour AS INTEGER)
DECLARE SUB neoDrawPolygonGouraud (Layer AS INTEGER, PolyArray() AS ANY)
DECLARE SUB neoDrawHLine (Layer AS INTEGER, OnY AS INTEGER, Colour AS INTEGER)
DECLARE SUB neoDrawVLine (Layer AS INTEGER, OnX AS INTEGER, Colour AS INTEGER)

DEFINT A-Z
'$DYNAMIC
'$INCLUDE: 'QB.BI'
'$INCLUDE: 'neoLAYER.bi'
'$INCLUDE: 'neoEMS.bi'

TYPE PolyStruct
        X AS INTEGER
        Y AS INTEGER
        C AS INTEGER
END TYPE

DIM SHARED DRAWhandle AS INTEGER
DIM SHARED ClipBox(4) AS INTEGER

'////////////////////////////////////////////////////////////////////////
' FUNCTIONS
'////////////////////////////////////////////////////////////////////////
FUNCTION neoDrawPoint (Layer AS INTEGER, fromX AS INTEGER, fromY AS INTEGER)
        'retrieves the colour of a specified pixel from a specific layer
        ' Layer = the layer to retrieve pixel data from
        ' fromX = the x coordinate of the pixel to read
        ' fromY = the y coordinate of the pixel to read

        IF Layer = VIDEO THEN
        	DEF SEG = &HA000
        	neoDrawPoint = PEEK(fromY * 320& + fromX)
        ELSE
        	colr% = 0
        	neoEMSmove DRAWhandle, (Layer - 1) * 4 + (320& * fromY + fromX) \ 16384, (320& * fromY + fromX) MOD 16384, 0, VARSEG(colr%), VARPTR(colr%), 1
        	neoDrawPoint = colr%
        END IF
END FUNCTION

'////////////////////////////////////////////////////////////////////////
' SUBS
'////////////////////////////////////////////////////////////////////////
SUB neoDrawInitLayers
	'initializes the draw module for use with the allocated layers
	'WARNING! Call this routine before using ANY draw routine!!!
	DRAWhandle = neoLayerGetHandle
	ClipBox(0) = 0
	ClipBox(1) = 319
	ClipBox(2) = 0
	ClipBox(3) = 199
END SUB

SUB neoDrawSetClipBox (X1 AS INTEGER, Y1 AS INTEGER, X2 AS INTEGER, Y2 AS INTEGER)
        'sets the clipbox for all drawfunctions in here
        ' X1 = upperleft-x
        ' Y1 = upperleft-y
        ' X2 = lowerright-x
        ' Y2 = lowerright-y

        ClipBox(0) = X1
        ClipBox(1) = X2
        ClipBox(2) = Y1
        ClipBox(3) = Y2
END SUB

SUB neoDrawPixel (Layer AS INTEGER, toX AS INTEGER, toY AS INTEGER, Colour AS INTEGER)
	'draws a pixel on the specified layer, use VIDEO to draw on the screen
	' Layer = the specified layer
	' toX = x position of the pixel (0-319)
	' toY = y position of the pixel (0-199)
	' Colour = color of the pixel (0-255)

	IF toX < ClipBox(0) OR toX > ClipBox(1) OR toY < ClipBox(2) OR toY > ClipBox(3) THEN EXIT SUB

        IF Layer = VIDEO THEN
                DEF SEG = &HA000
                POKE toY * 320& + toX, Colour
        ELSE
        	neoEMSmove 0, VARSEG(Colour), VARPTR(Colour), DRAWhandle, (Layer - 1) * 4 + INT((toY * 320& + toX) / 16384), (toY * 320& + toX) MOD 16384, 1
        END IF
END SUB

SUB neoDrawLine (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER)
	'draws a line with the specified colour
	' Layer = layer to draw the line on
	' StartX = the start x coordinate of the line
	' StartY = the start y coordinate of the line
	' EndX = the end x coordinate of the line
	' EndY = the end y coordinate of the line
	' Colour = the color of the line

	'the end and start coordinates may not be the same
	IF (StartX = EndX) AND (StartY = EndY) THEN
		neoDrawPixel Layer, StartX, StartY, Colour
		EXIT SUB
	END IF

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSEIF Layer = -1 THEN 'needed for neoDrawCircle and neoDrawEllipse and neoDrawPolygon
		DEF SEG = neoEMSpageFrame
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

        difX = ABS(EndX - StartX)
        difY = ABS(EndY - StartY)
        IF difX >= difY THEN
        	stepfactor = SGN(EndX - StartX)
        	IF stepfactor = 0 THEN stepfactor = 1
        	nowyc# = StartY
        	stepy# = CDBL(EndY - StartY) / ABS(EndX - StartX)
                FOR xc = StartX TO EndX STEP stepfactor
                	IF xc >= ClipBox(0) AND xc <= ClipBox(1) AND INT(nowyc#) >= ClipBox(2) AND INT(nowyc#) <= ClipBox(3) THEN POKE INT(nowyc#) * 320& + xc, Colour
                        nowyc# = nowyc# + stepy#
                NEXT xc
        ELSE
        	stepfactor = SGN(EndY - StartY)
        	IF stepfactor = 0 THEN stepfactor = 1
        	nowxc# = StartX
        	stepx# = CDBL(EndX - StartX) / ABS(EndY - StartY)
        	FOR yc = StartY TO EndY STEP stepfactor
        		IF INT(nowxc#) >= ClipBox(0) AND INT(nowxc#) <= ClipBox(1) AND yc >= ClipBox(2) AND yc <= ClipBox(3) THEN POKE yc * 320& + INT(nowxc#), Colour
        		nowxc# = nowxc# + stepx#
        	NEXT yc
        END IF

        IF (Layer <> VIDEO) AND (Layer <> -1) THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawLineGouraud (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, StartCol AS INTEGER, EndCol AS INTEGER)
	'draws a gouraud shaded line with the specified colours
	' Layer = layer to draw the line on
	' StartX = the start x coordinate of the line
	' StartY = the start y coordinate of the line
	' EndX = the end x coordinate of the line
	' EndY = the end y coordinate of the line
	' StartCol = the startcolor of the line
	' EndCol = the endcolor of the line

	IF (StartX = EndX) AND (StartY = EndY) THEN
		neoDrawPixel Layer, StartX, StartY, StartCol
		EXIT SUB
	END IF

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSEIF Layer = -1 THEN	'needed for neoDrawPolygonGouraud
		DEF SEG = neoEMSpageFrame
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

        difX = ABS(EndX - StartX)
        difY = ABS(EndY - StartY)
        IF difX >= difY THEN
        	stepfactor = SGN(EndX - StartX)
        	IF stepfactor = 0 THEN stepfactor = 1
        	nowyc# = StartY
        	nowc# = StartCol
        	stepy# = CDBL(EndY - StartY) / ABS(EndX - StartX)
        	stepc# = CDBL(EndCol - StartCol) / ABS(EndX - StartX)
                FOR xc = StartX TO EndX STEP stepfactor
                        IF xc >= ClipBox(0) AND xc <= ClipBox(1) AND INT(nowyc#) >= ClipBox(2) AND INT(nowyc#) <= ClipBox(3) THEN POKE INT(nowyc#) * 320& + xc, INT(nowc#)
                        nowyc# = nowyc# + stepy#
                        nowc# = nowc# + stepc#
                NEXT xc
        ELSE
        	stepfactor = SGN(EndY - StartY)
        	IF stepfactor = 0 THEN stepfactor = 1
        	nowxc# = StartX
        	nowc# = StartCol
        	stepx# = CDBL(EndX - StartX) / ABS(EndY - StartY)
        	stepc# = CDBL(EndCol - StartCol) / ABS(EndY - StartY)
        	FOR yc = StartY TO EndY STEP stepfactor
        		IF INT(nowxc#) >= ClipBox(0) AND INT(nowxc#) <= ClipBox(1) AND yc >= ClipBox(2) AND yc <= ClipBox(3) THEN POKE yc * 320& + INT(nowxc#), INT(nowc#)
        		nowxc# = nowxc# + stepx#
        		nowc# = nowc# + stepc#
        	NEXT yc
        END IF

        IF (Layer <> VIDEO) AND (Layer <> -1) THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawBox (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER)
        'draws a box on the specified layer
        ' Layer = the layer to draw the box on
        ' StartX = the upperleft x coordinate
        ' StartY = the upperleft y coordinate
        ' EndX = the lowerright x coordinate
        ' EndY = the lowerright y coordinate
        ' Colour = the colour of the box

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

	stepfactor = SGN(EndX - StartX)
	IF stepfactor = 0 THEN stepfactor = 1
	syin = (StartY >= ClipBox(2) AND StartY <= ClipBox(3))
	eyin = (EndY >= ClipBox(2) AND EndY <= ClipBox(3))
        FOR xc = StartX TO EndX STEP stepfactor
        	IF xc >= ClipBox(0) AND xc <= ClipBox(1) THEN
                	IF syin THEN POKE StartY * 320& + xc, Colour
                	IF eyin THEN POKE EndY * 320& + xc, Colour
                END IF
        NEXT xc
        stepfactor = SGN(EndY - StartY)
        IF stepfactor = 0 THEN stepfactor = 1
        sxin = (StartX >= ClipBox(0) AND StartX <= ClipBox(1))
	exin = (EndX >= ClipBox(0) AND EndX <= ClipBox(1))
        FOR yc = StartY TO EndY STEP stepfactor
        	IF yc >= ClipBox(2) AND yc <= ClipBox(3) THEN
        		IF sxin THEN POKE yc * 320& + StartX, Colour
        		IF exin THEN POKE yc * 320& + EndX, Colour
        	END IF
        NEXT yc

        IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawBoxF (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER)
	'draws a filled box on the specified layer
        ' Layer = the layer to draw the box on
        ' StartX = the upperleft x coordinate
        ' StartY = the upperleft y coordinate
        ' EndX = the lowerright x coordinate
        ' EndY = the lowerright y coordinate
        ' Colour = the colour of the box

        IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

        stepfx = SGN(EndX - StartX)
        stepfy = SGN(EndY - StartY)
        IF stepfx = 0 THEN stepfx = 1
        IF stepfy = 0 THEN stepfy = 1
        FOR yc = StartY TO EndY STEP stepfy
        	ycin = (yc >= ClipBox(2) AND yc <= ClipBox(3))
        	FOR xc = StartX TO EndX STEP stepfx
        		IF ycin AND (xc >= ClipBox(0) AND xc <= ClipBox(1)) THEN
        			POKE yc * 320& + xc, Colour
        		END IF
        	NEXT xc
        NEXT yc

	IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawBoxTrans (Layer AS INTEGER, StartX AS INTEGER, StartY AS INTEGER, EndX AS INTEGER, EndY AS INTEGER, Colour AS INTEGER, StdPal AS STRING, Neg AS INTEGER)
	'draws a filled blended box on the specified layer
        ' Layer = the layer to draw the box on
        ' StartX = the upperleft x coordinate
        ' StartY = the upperleft y coordinate
        ' EndX = the lowerright x coordinate
        ' EndY = the lowerright y coordinate
        ' Colour = the colour of the box
        ' StdPal: the current 768-byte string palette
        ' Neg: FALSE for positive blending, TRUE for negative blending

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

        stepfx = SGN(EndX - StartX)
        stepfy = SGN(EndY - StartY)
        IF stepfx = 0 THEN stepfx = 1
        IF stepfy = 0 THEN stepfy = 1
        FOR yc = StartY TO EndY STEP stepfy
        	ycin = (yc >= ClipBox(2) AND yc <= ClipBox(3))
        	FOR xc = StartX TO EndX STEP stepfx
        		IF ycin AND (xc >= ClipBox(0) AND xc <= ClipBox(1)) THEN
        			valuehere% = Colour
        			valuethere% = PEEK(yc * 320& + xc)

        			aR = ASC(MID$(StdPal, valuehere% * 3 + 1, 1))
 				aG = ASC(MID$(StdPal, valuehere% * 3 + 2, 1))
 				aB = ASC(MID$(StdPal, valuehere% * 3 + 3, 1))

 				dR = ASC(MID$(StdPal, valuethere% * 3 + 1, 1))
 				dG = ASC(MID$(StdPal, valuethere% * 3 + 2, 1))
 				dB = ASC(MID$(StdPal, valuethere% * 3 + 3, 1))

				IF Neg THEN
					mR = ABS(aR - dR)
					mG = ABS(aG - dG)
					mB = ABS(aB - dB)
				ELSE
 					mR = aR + dR
 					mG = aG + dG
 					mB = aB + dB
 					IF mR > 63 THEN mR = 63
 					IF mG > 63 THEN mG = 63
 					IF mB > 63 THEN mB = 63
 				END IF

				'search best matching color in StdPal, equal to neoPalSearchIn
 				mindif% = 32000
 				minimum% = 0
 				FOR checkC = 0 TO 255
					aR = ASC(MID$(StdPal, checkC * 3 + 1, 1))
					aG = ASC(MID$(StdPal, checkC * 3 + 2, 1))
					aB = ASC(MID$(StdPal, checkC * 3 + 3, 1))
                                	dif% = ABS(mR - aR) + ABS(mG - aG) + ABS(mB - aB)
                                	IF dif% < mindif% THEN mindif% = dif%: minimum% = checkC
 				NEXT checkC

        			POKE yc * 320& + xc, minimum%
        		END IF
        	NEXT xc
        NEXT yc

	IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawCircle (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, Radius AS INTEGER, Colour AS INTEGER)
        'draws a circle on a layer
        ' Layer = the layer to draw circle on
        ' MiddleX = the x-coordinate of the center of the circle
        ' MiddleY = the y-coordinate of the center of the circle
        ' Radius = the radius of the circle
        ' Colour = the color of the circle

        IF Layer = VIDEO THEN
        	DEF SEG = &HA000
        ELSE
        	neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
        	pF% = neoEMSpageFrame
        	DEF SEG = pF%
        END IF

        IF Radius = 0 THEN
        	neoDrawPixel Layer, MiddleX, MiddleY, Colour
        	EXIT SUB
        END IF

        'solve with formula: r^2=x^2+y^2 (Pythagoras)
        'x=SQR(r^2 - y^2)
        'or
        'y=SQR(r^2 - x^2)
        MinX = -Radius
        MaxX = Radius
        lastY = 0
        FOR xc = MinX + 1 TO MaxX
                yc = INT(SQR(CLNG(Radius) ^ 2& - CLNG(xc) ^ 2&))
                realX = xc + MiddleX
                realY1 = yc + MiddleY
                realY2 = MiddleY - yc

		IF Layer <> VIDEO THEN
                	neoDrawLine -1,realX-1,lastY+MiddleY,realX,realY1,Colour
                	neoDrawLine -1,realX-1,MiddleY-lastY,realX,realY2,Colour
                ELSE
                	neoDrawLine VIDEO,realX-1,lastY+MiddleY,realX,realY1,Colour
                	neoDrawLine VIDEO,realX-1,MiddleY-lastY,realX,realY2,Colour
                END IF

                lastY = yc
        NEXT xc

        IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawCircleF (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, Radius AS INTEGER, Colour AS INTEGER)
	'draws a filled circle on a layer
        ' Layer = the layer to draw circle on
        ' MiddleX = the x-coordinate of the center of the circle
        ' MiddleY = the y-coordinate of the center of the circle
        ' Radius = the radius of the circle
        ' Colour = the color of the circle

	IF Layer = VIDEO THEN
        	DEF SEG = &HA000
        ELSE
        	neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
        	pF% = neoEMSpageFrame
        	DEF SEG = pF%
        END IF

        IF Radius = 0 THEN
        	neoDrawPixel Layer, MiddleX, MiddleY, Colour
        	EXIT SUB
        END IF

        'solve with formula: r^2=x^2+y^2 (Pythagoras)
        'x=SQR(r^2 - y^2)
        'or
        'y=SQR(r^2 - x^2)
        MinX = -Radius
        MaxX = Radius
        FOR xc = MinX TO MaxX
                yc = INT(SQR(CLNG(Radius) ^ 2& - CLNG(xc) ^ 2&))
                realX = xc + MiddleX
                realY1 = yc + MiddleY
                realY2 = MiddleY - yc

                FOR ycx = realY2 TO realY1
                        IF realX >= ClipBox(0) AND realX <= ClipBox(1) AND ycx >= ClipBox(2) AND ycx <= ClipBox(3) THEN POKE ycx * 320& + realX, Colour
                NEXT ycx
        NEXT xc

        IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawEllipse (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, XRadius AS INTEGER, YRadius AS INTEGER, Colour AS INTEGER)
	'draws an ellipse on a layer
        ' Layer = the layer to draw ellipse on
        ' MiddleX = the x-coordinate of the center of the ellipse
        ' MiddleY = the y-coordinate of the center of the ellipse
        ' XRadius = the radius on the x-side of the ellipse
        ' YRadius = the radius on the y-side of the ellipse
        ' Colour = the color of the ellipse
        'NOTE: you can't draw rotated ellipses yet!

        IF Layer = VIDEO THEN
        	DEF SEG = &HA000
        ELSE
        	neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
        	pF% = neoEMSpageFrame
        	DEF SEG = pF%
        END IF

        IF XRadius = 0 OR YRadius = 0 THEN
        	neoDrawPixel Layer, MiddleX, MiddleY, Colour
        	EXIT SUB
        END IF

        'solve using Pythagoras: r^2=x^2+y^2
        MinX = -XRadius
        MaxX = XRadius
        verh# = CDBL(YRadius / XRadius)
        FOR xc = MinX TO MaxX
        	yc = INT(SQR(XRadius ^ 2& - xc ^ 2&) * verh#)
                realX = xc + MiddleX
                realY1 = yc + MiddleY
                realY2 = MiddleY - yc

 		IF xc <> MinX THEN
                        IF Layer <> VIDEO THEN
                        	neoDrawLine -1,realX-1,lastY+MiddleY,realX,realY1,Colour
                        	neoDrawLine -1,realX-1,MiddleY-lastY,realX,realY2,Colour
                        ELSE
                        	neoDrawLine VIDEO,realX-1,lastY+MiddleY,realX,realY1,Colour
                        	neoDrawLine VIDEO,realX-1,MiddleY-lastY,realX,realY2,Colour
                        END IF
 		END IF

 		lastY = yc
        NEXT xc

        IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawEllipseF (Layer AS INTEGER, MiddleX AS INTEGER, MiddleY AS INTEGER, XRadius AS INTEGER, YRadius AS INTEGER, Colour AS INTEGER)
	'draws a filled ellipse on a layer
        ' Layer = the layer to draw ellipse on
        ' MiddleX = the x-coordinate of the center of the ellipse
        ' MiddleY = the y-coordinate of the center of the ellipse
        ' XRadius = the radius on the x-side of the ellipse
        ' YRadius = the radius on the y-side of the ellipse
        ' Colour = the color of the ellipse
        'NOTE: you can't draw filled rotated ellipses yet!
        'REMARK: this function is almost as fast as neoDrawEllipse!!!

        IF Layer = VIDEO THEN
        	DEF SEG = &HA000
        ELSE
        	neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
        	pF% = neoEMSpageFrame
        	DEF SEG = pF%
        END IF

        IF XRadius = 0 OR YRadius = 0 THEN
        	neoDrawPixel Layer, MiddleX, MiddleY, Colour
        	EXIT SUB
        END IF

        'use the Pythagoras formula, r^2=x^2+y^2, for the ellipse drawing
        verh# = CDBL(YRadius / XRadius)
        MinX = -XRadius
        MaxX = XRadius
        FOR xc = MinX TO MaxX
                yc = INT(SQR(XRadius ^ 2& - xc ^ 2&) * verh#)
                realX = xc + MiddleX
                realY1 = yc + MiddleY
                realY2 = MiddleY - yc

                xcin = ((realX >= ClipBox(0)) AND (realX <= ClipBox(1)))
                FOR ryc = realY2 TO realY1
                	IF xcin THEN
                		IF ryc >= ClipBox(2) AND ryc <= ClipBox(3) THEN POKE 320& * ryc + realX, Colour
                	END IF
                NEXT ryc
        NEXT xc

        IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawPolygon (Layer AS INTEGER, PolyArray() AS PolyStruct, Colour AS INTEGER)
	'draws a polygon on the specified layer
	' Layer = the layer to draw on
	' PolyArray() = the array containing X and Y info of each point
	' Colour = the color to draw the polygon with
	' WARNING: PolyArray() must contain at least 2 points!!!

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

	lb = LBOUND(PolyArray)
	ub = UBOUND(PolyArray)
        IF lb = ub THEN
        	neoDrawPixel Layer, PolyArray(lb).X, PolyArray(lb).Y, Colour
        	EXIT SUB
        END IF

        FOR index = lb TO ub - 1
                IF Layer <> VIDEO THEN
                	neoDrawLine -1,PolyArray(index).X,PolyArray(index).Y,PolyArray(index+1).X,PolyArray(index+1).Y,Colour
                ELSE
                	neoDrawLine VIDEO,PolyArray(index).X,PolyArray(index).Y,PolyArray(index+1).X,PolyArray(index+1).Y,Colour
                END IF
        NEXT index
        IF Layer <> VIDEO THEN
        	neoDrawLine -1,PolyArray(ub).X,PolyArray(ub).Y,PolyArray(lb).X,PolyArray(lb).Y,Colour
        ELSE
        	neoDrawLine VIDEO,PolyArray(ub).X,PolyArray(ub).Y,PolyArray(lb).X,PolyArray(lb).Y,Colour
        END IF

        IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawPolygonGouraud (Layer AS INTEGER, PolyArray() AS PolyStruct)
	'draws a gouraud shaded polygon on the specified layer
	' Layer = the layer to draw on
	' PolyArray() = the array containing X, Y and C info of each point
	' WARNING: PolyArray() must contain at least 2 points!!!

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

	lb = LBOUND(PolyArray)
	ub = UBOUND(PolyArray)
        IF lb = ub THEN
        	neoDrawPixel Layer, PolyArray(lb).X, PolyArray(lb).Y, PolyArray(lb).C
        	EXIT SUB
        END IF

        FOR index = lb TO ub - 1
                IF Layer <> VIDEO THEN
                	neoDrawLineGouraud -1,PolyArray(index).X,PolyArray(index).Y,PolyArray(index+1).X,PolyArray(index+1).Y,PolyArray(index).C,PolyArray(index+1).C
                ELSE
                	neoDrawLineGouraud VIDEO,PolyArray(index).X,PolyArray(index).Y,PolyArray(index+1).X,PolyArray(index+1).Y,PolyArray(index).C,PolyArray(index+1).C
                END IF
        NEXT index
        IF Layer <> VIDEO THEN
        	neoDrawLineGouraud -1,PolyArray(ub).X,PolyArray(ub).Y,PolyArray(lb).X,PolyArray(lb).Y,PolyArray(ub).C,PolyArray(lb).C
        ELSE
        	neoDrawLineGouraud VIDEO,PolyArray(ub).X,PolyArray(ub).Y,PolyArray(lb).X,PolyArray(lb).Y,PolyArray(ub).C,PolyArray(lb).C
        END IF

        IF Layer <> VIDEO THEN
        	FOR I = 0 TO 3
        		neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
        	NEXT I
        END IF
END SUB

SUB neoDrawHLine (Layer AS INTEGER, OnY AS INTEGER, Colour AS INTEGER)
	'draws a horizontal line on a layer
	' Layer = the layer to draw on
	' OnY = the Y-coordinate of the line
	' Colour = the colour of the line

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

        IF OnY >= ClipBox(2) AND OnY <= ClipBox(3) THEN
        	ony320& = 320& * OnY
        	FOR OnX = 0 TO 319
        		IF OnX >= ClipBox(0) AND OnX <= ClipBox(1) THEN POKE ony320& + OnX, Colour
        	NEXT OnX
        END IF

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
			neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

SUB neoDrawVLine (Layer AS INTEGER, OnX AS INTEGER, Colour AS INTEGER)
	'draws a vertical line on a layer
	' Layer = the layer to draw on
	' OnX = the X-coordinate of the line
	' Colour = the colour of the line

	IF Layer = VIDEO THEN
		DEF SEG = &HA000
	ELSE
		neoEMSmapX (Layer - 1) * 4, 0, 4, DRAWhandle
		pF% = neoEMSpageFrame
		DEF SEG = pF%
	END IF

	IF OnX >= ClipBox(0) AND OnX <= ClipBox(1) THEN
		FOR OnY = 0 TO 199
			IF OnY >= ClipBox(2) AND OnY <= ClipBox(3) THEN POKE OnY * 320& + OnX, Colour
		NEXT OnY
	END IF

	IF Layer <> VIDEO THEN
		FOR I = 0 TO 3
			neoEMSmove 0, pF%, &H4000& * I, DRAWhandle, (Layer - 1) * 4 + I, 0, 16384
		NEXT I
	END IF
END SUB

