
#define TIEFE 4
#define BREITE 320
#define HOEHE 200
#define FARBEN 16
#define RASTERBREITE 640
#define RASTERHOEHE 400
#define VERSION 29
#define FARBWECHSEL 5
#define CYCLEWECHSEL 13
#define STEP 3
#define P 0.03117
#define Q 1.12104

#include <exec/types.h>		/* allgem. Typen-Def. */
#include <graphics/gfx.h>	/* Grafik-Headers ... */
#include <graphics/gfxmacros.h>
#include <graphics/view.h>
#include <functions.h>
#include <math.h>

struct GfxBase *GfxBase;

UWORD Farbtabelle[FARBEN] =
	{0x0000,0x0fff,0x0bbb,0x0777,0x000f,0x002b,0x0047,0x0f00,
	 0x0b20,0x0740,0x0ff0,0x0bb0,0x0770,0x00f0,0x01b1,0x0373};
UWORD Ecken[8];

main()
{
	struct View v;		/* View Struktur erzeugen */
	struct ViewPort vp;	/* ViewPort erzeugen */
	struct RasInfo ri;	/* RasInfo Struktur erzeugen */
	struct BitMap b;	/* Platz fuer BitMap belegen */
	struct RastPort rp;	/* RastPort (fuers Zeichnen) */
	register LONG i;	/* Arbeitsvariablen */
	register UWORD x,y,j;
	UBYTE z;
	SHORT dx=0,dy=0;
	float sc,w=0;

	GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",VERSION);
	if (GfxBase == NULL) {
		printf("GRAPHICS LIBRARY NOT FOUND!!\n");
		exit(0);
	}
	InitView(&v);	/* View Struktur init. */
	v.ViewPort=&vp;	/* ViewPort und View Struktur linken */

	OFF_DISPLAY;

	InitBitMap(&b,TIEFE,RASTERBREITE,RASTERHOEHE);	/* BitMap init. */

	for(i=0;i<TIEFE;i++) {
		b.Planes[i]=AllocRaster(RASTERBREITE,RASTERHOEHE);
		if (b.Planes[i]==0L) printf("No Memory For Display!\n");
	}
	
	ri.BitMap=&b;	/* RasInfo Struktur init. */
	ri.RxOffset=0;	/* linke, obere Ecke des Rasters */
	ri.RyOffset=0;

	InitVPort(&vp);	/* ViewPort init. */
	vp.DWidth=BREITE;
	vp.DHeight=HOEHE;
	vp.RasInfo=&ri;

	MakeVPort(&v,&vp);	/* View erzeugen mit den vorbereiteten
				   Strukturen */
	MrgCop(&v);	/* die Coprozessor-Instruktionen dieser View in eine
			   Instruktionsliste */
	LoadView(&v);	/* dies zur aktuellen View machen, Copper starten */

	InitRastPort(&rp);	
	rp.BitMap=&b;

	SetRast(&rp,0L);	/* Raster loeschen, Farbe = 0 */
	SetBPen(&rp,0L);	/* Hintergrundfarbe */
	SetDrMd(&rp,JAM1); /* Zeichenmodus */
	ON_DISPLAY;
	for(i=1; i<=100000; i++) {
		if(i%FARBWECHSEL==0L)
			SetAPen(&rp,(++z)%FARBEN);	/* Zeichenfarbe setzen */
		x=i*STEP%RASTERBREITE;
		y=i*STEP%RASTERHOEHE;
		/* zentriertes Rechteck mit x,y als linker oberer Ecke */
		Move(&rp,x,y);	
		Ecken[0]=RASTERBREITE-x; Ecken[1]=y;
		Ecken[2]=RASTERBREITE-x; Ecken[3]=RASTERHOEHE-y;
		Ecken[4]=x;		 Ecken[5]=RASTERHOEHE-y;
		Ecken[6]=x;		 Ecken[7]=y;
		PolyDraw(&rp,4L,Ecken);
		w+=P;
		sc=sin(w)+1;
		dx=(RASTERBREITE-BREITE-2)/2 * sc;
		sc=cos(w*Q)+1;
		dy=(RASTERHOEHE-HOEHE-2)/2 * sc;

		ri.RxOffset=dx;
		ri.RyOffset=dy;
		ScrollVPort(&vp);
	}
	SetRast(&rp,0);
}

Cycle(vp)
struct ViewPort *vp;
{
	register short i;
	UWORD h;

	h=Farbtabelle[1];
	for(i=1; i<FARBEN-1; i++) 
		Farbtabelle[i]=Farbtabelle[i+1];
	Farbtabelle[FARBEN-1]=h;
	LoadRGB4(vp,Farbtabelle,FARBEN);
}
