// 
//	line.c: (C) Clemens Marschner, 1996
//

#include <pragma/graphics_lib.h>
#include <pragma/exec_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/dos_lib.h>

struct GfxBase 		*GfxBase;
struct IntuitionBase *IntuitionBase;

void Zeichne(struct RastPort*);

void main() {
	struct Window *win;
	if(GfxBase = (struct GfxBase*)OpenLibrary("graphics.library",0l)) 
	{
		if(IntuitionBase = (struct IntuitionBase*)OpenLibrary("intuition.library",0l))
		{
			if(win = OpenWindowTags(0, WA_Title, "Linien", TAG_END, 0))
			{
				Zeichne(win->RPort);
				Delay(4*50);		/* vier Sekunden warten */
				CloseWindow(win);
			}
			CloseLibrary((struct Library*)IntuitionBase);
		}
		CloseLibrary((struct Library*)GfxBase);
	}
}


int round(double v) {
	return (int)(v+0.5);
}

// Folgende Routinen nur gültig für 0<=m<=1 (Linie zw. 0 und 45°)
// in Wirklichkeit noch Spiegelungen notwendig

void Line_1(struct RastPort *rp, int x1, int y1, int x2, int y2)
{
	double m,y;
	int x;
	m = ((double)(y2-y1))/(x2-x1); /* durch "float" werden die Koordinaten in 
												Fließkommazahlen umgewandelt */
	for(x=x1,y=y1; x<=x2; x++) 
	{
		WritePixel(rp, x, round(y));
		y += m;
	}
}

void Line_2(struct RastPort *rp, int x1, int y1, int x2, int y2) 
{
	double m,error = 0;
	m = ((double)(y2-y1))/(x2-x1);
	int y = y1;
	for(int x = x1; x<=x2; x++) {
		WritePixel(rp, x,y);
		error += m;
		if (error >= 0.5) {
			y++; 
			error--;
		}
	}
}

void Line_3(struct RastPort *rp, int x1, int y1, int x2, int y2) 
{
	int m = 2*(y2-y1), error = 0;
	int y = y1;
	for(int x = x1; x<=x2; x++) {
		WritePixel(rp, x,y);
		error += m;
		if (error >= x2-x1) {
			y++; 
			error-= 2*(x2-x1);
		}
	}
}



void Zeichne(struct RastPort*rp) {
	int i;
	SetAPen(rp,1);
	for(i=0; i<60; i+=2) {
		Line_1(rp, 10+6*i,2*i+20, 600,4*i+20);
	}
	SetAPen(rp,2);
	for(i=0; i<60; i+=2) {
		Line_2(rp, 10+6*i,2*i+20, 600,4*i+20);
	}
	SetAPen(rp,3);
	for(i=0; i<60; i+=2) {
		Line_2(rp, 10+6*i,2*i+20, 600,4*i+20);
	}
}

