/*
	POLY.C

	Example of polygon drawing functions.
*/

#define APP 1
#use vdriver.lib
#use kp.lib
#use wintek.lib
#use glcd.lib

#if 0
ASM_NOIX void _glPlotVLine(int x1, int y1, int x2, int y2) {
	auto struct glBuf displayBuf;
	auto int swapper;
	auto int i;

	glBufOpen(&displayBuf);	
	if (y1 > y2) {
		SWAP(y1,y2);
	}
	for (i = y1; i <= y2; ++i) glBufPlotDot(&displayBuf,x1,i);
	glBufClose(&displayBuf);
}
#endif

/*

gl		-	graphics LCD: this is the abstract graphics LCD library

kp		-	keypad: this is the keypad functions

wt		-	winTek LCD controler

kdi	-	keypad-display interface: this is the thing that sits
			between the controler and the winTek LCD controller
			
lp		-	lcd port: this is the port on the controler

*/

void glPlotPolySeg(int n, int *pFirstV, int x) {
	auto int minY,min2Y,min3Y,swapper;
	auto int yBound;
	auto int c1,c2;
	auto int y;
	auto int i;
	auto int *pCurrentV;
	auto int x1,y1,x2,y2;

	minY = 0x7fff;
	yBound = 0;
	c1 = c2 = 0;
	do {
		pCurrentV = pFirstV;
		min2Y = min3Y = 0x7fff;
		for (i = 0; i < n; ++i) {
			x1 = pCurrentV[0];
			y1 = pCurrentV[1];
			if (i != n-1) {
				x2 = pCurrentV[2];
				y2 = pCurrentV[3];
			} else {
				x2 = pFirstV[0];
				y2 = pFirstV[1];
			}
			if (((x1 <= x) && (x2 >= x)) ||
				 ((x2 <= x) && (x1 >= x))) {
				if (x1 == x2) {
					if (y2 < y1) SWAP(y1,y2);
					if (y1 < minY) minY = (y1 < yBound)?yBound:y1;
					if (y2 > min2Y) min2Y = y2;
					if (y2 >= min3Y) min3Y = 0x7fff;
				} else {
					y = (int)(y1 +
						(float)((x-x1) * (y2 - y1)) /
							(x2 - x1));
					if (y > 63) y;
					if (y >= yBound) {
						if (y < minY) {
							if (min2Y != y) min3Y = min2Y;
							min2Y = minY;
							minY = y;
							c2 = c1;
							c1 = 0;
						} else if (y < min2Y) {
							if (min2Y != y) min3Y = min2Y;
							min2Y = y;
							c2 = 0;
						} else if (y < min3Y) {
							if (min2Y != y) min3Y = y;
						}
						if (y == minY) ++c1;
						if (y == min2Y) ++c2;
					}
				}
			}
			pCurrentV += 2;
		}
		if (min2Y != 0x7fff) {
			if (minY == min2Y) {
				if (c1 & 1) {
					if (min3Y != 0x7fff) {
						glPlotVLine(x,minY,x,min3Y);
						c1 = 1;
						minY = min3Y;
						yBound = min3Y+1;
					}
				} else {
					glPlotVLine(x,minY,x,minY);
					c1 = 0;
					yBound = min3Y;
					minY = 0x7fff;
				}
			} else {
				glPlotVLine(x,minY,x,min2Y);
				minY = (c2&1)?0x7fff:min2Y;
				yBound = (c2&1)?min3Y:(min2Y+1);
				c1 = !(c2&1);
			}
		}
		if (min3Y != 0x7fff) min3Y;
	} while (min3Y != 0x7fff);
}

main() {
	unsigned long timeMark;
	
	VdInit();
	glInit();
	glBlankScreen();
	while (1) {
		glBlankScreen();
		glSetBrushType(GL_XOR);
		glFillPolygon(5,23,45,88,63,43,0,99,56,2,1);
		glFillCircle(64,32,24);
		glSetBrushType(GL_SET);
		timeMark = MS_TIMER;
		while (MS_TIMER-timeMark < 500);
		glBlankScreen();
		glPlotPolygon(5,23,45,88,63,43,0,99,56,2,1);
		glPlotCircle(64,32,24);
		timeMark = MS_TIMER;
		while (MS_TIMER-timeMark < 500);
	}
}
