/**********************************************************/
/*                      ViewPort3.c                       */
/*                         V 1.5                          */
/**********************************************************/
/* von Frank Stratmann 		10-11/01/1989             */
/**********************************************************/
/* das kleine grafik-demo ist PUPLIC-DOMAIN		  */
/**********************************************************/

#include "exec/types.h"
#include "exec/memory.h"
#include "exec/tasks.h"
#include "exec/nodes.h"
#include "graphics/gfxmacros.h"
#include "graphics/sprite.h"
#include "graphics/gfx.h"
#include "graphics/rastport.h"
#include "graphics/view.h"
#include "graphics/gels.h"
#include "graphics/regions.h"
#include "graphics/clip.h"
#include "graphics/text.h"
#include "graphics/gfxbase.h"
#include "hardware/blit.h"

#define DEPTHV1 6                        		/* 6 BitPlanes */
#define DEPTHV2 6
#define DEPTHV3 3
#define WIDTH 620                     		/* 620 x 256 Punkte sind im View möglich */
#define HEIGHT 256
#define MODE0 0					/* Im View ist HIRES möglich */
#define MODE1 HAM|SPRITES
#define MODE2 HAM					/* Modes für ViewPorts */
#define MODE3 DUALPF				/* Mode für Playfields ! */

#define V1WIDTH 620				/* Breite des ersten ViewPorts */
#define V1HEIGHT 100				/* Höhe des ersten Viewports */
#define V2WIDTH 340				/* Breite des zweiten ViewPorts */
#define V2HEIGHT 50				/* Höhe des zweiten ... */
#define V3WIDTH 320
#define V3HEIGHT 90

#define NOT_ENOUGH_MEMORY -1000
#define RUNTER 6

struct View View;            			/* Struktur für neuen View */
struct ViewPort ViewPort[3];			/* Strukturen für die drei ViewPorts */
struct RasInfo RasInfo[4];			/* Strukturen für RasInfo`s */
struct ColorMap *ColorMap;			/* ColorMap: Zeiger auf ColorMap-Struktur */
struct BitMap BitMap[4];			/* Vier BitMaps: Speicher für Grafikdaten */
struct RastPort RastPort[4];			/* Vier RastPorts nötig: fürs Malen */
struct SimpleSprite SimpleSprite;		/* Schlüssel für alle Befehle für Sprites */

SHORT i,j,g,h,n,a,f,b,z1,z2,status;					/* Schleifenvariablen */


struct GfxBase *GfxBase;			/* GfxBase: Zeiger auf BfxBase-Struktur */
struct View *oldView;				/* Hier wird der alte View gerettet */

USHORT color1[]={0x000,0xff0,0x0ff,0xf0f,
		 0xf00,0x00f,0x11f,0x069,
		 0xb3d,0xc9c,0x0f0,0x789,
		 0xb5f,0x936,0xabf,0xf00,
		 0x0f0,0x00f,0xf00};	/* Farbwerte für die jeweiligen */
USHORT color2[]={0x000,0x0f9,0x11f,0x1f1,
		 0x123,0x1bd,0x0ff,0xf0f,
		 0xb5f,0x120,0x936,0xabf,
		 0xaf0,0xfd9,0x361,0x000};	/* Register der RastPorts u. */
USHORT color3[]={0x000,0x012,0x123,0x234,	/* BitMaps etc.: für HIRES, */
		 0x345,0x456,0x567,0x678,	/* Mittelding !?! , und für */
		 0xf11,0xf22,0xf33,0xf44,
		 0xf55,0xf66,0xf77,0xf88};			/* PLAYFIELDS (DUALPF) . */
UWORD SpriteDaten[]={0,0,
		0,0,
		0x0200,0x0000,
		0x0500,0x0000,
		0x0880,0x0000,
		0x1240,0x0000,
		0x25a0,0x0000,
		0x0860,0x0000,
		0x1370,0x0000,
		0x07fc,0x0000,
		0x077c,0x0000,
		0x001c,0x0000,
		0x001c,0x3e00,
		0x0024,0x2200,
		0x0048,0x3e00,
		0x0090,0x3e00,
		0x004e,0x7f00,
		0x0020,0x0000,
		0x0010,0x0000,
		0,0};

UWORD *ChipSpriteD,*Help;

SHORT data[3][150];
char *LeftMouse=(char*)0xBFE001;

VOID draw();                       		/* Vorwärtsdeklaration */
VOID FreeMemory();

main()
{
	if((GfxBase=(struct GfxBase*)OpenLibrary("graphics.library",0))==NULL)
		exit(1);
	oldView=GfxBase->ActiView;		/* alten View retten */
	InitView(&View);			/* View initialisiren */
	InitVPort(&ViewPort[0]);		/* ViewPorts ini. */
	InitVPort(&ViewPort[1]);
	InitVPort(&ViewPort[3]);
	View.ViewPort=&ViewPort[0];		/* View mit ersten ViewPort verbinden */
	View.Modes=MODE0;
	InitBitMap(&BitMap[0],DEPTHV1,V1WIDTH,V1HEIGHT);		/* BitMap initialisieren */
	InitBitMap(&BitMap[1],DEPTHV2,V2WIDTH+600,V2HEIGHT);	/* hier: V2WIDTH+600 wegen Scrollen */
	InitBitMap(&BitMap[2],DEPTHV3,V3WIDTH,V3HEIGHT+10);
	InitBitMap(&BitMap[3],DEPTHV3,V3WIDTH,V3HEIGHT+10);
	for(i=0;i<2;i++)			/* RasInfo`s installieren */
	{
		RasInfo[i].BitMap=&BitMap[i];	/* RasInfo mit BitMap verbinden */
		RasInfo[i].RxOffset=0;		/* X-Position in BitMap wird an X-Position 0 im View dargestellt */
		RasInfo[i].RyOffset=0;		/* wie bei X nur mit Y */
		RasInfo[i].Next=NULL;		/* nächste RasInfo */
	}
	RasInfo[2].BitMap=&BitMap[2];		/* RasInfo`s für PLAYFIELDS installieren */
	RasInfo[2].RxOffset=0;	
	RasInfo[2].RyOffset=0;
	RasInfo[2].Next=&RasInfo[3];		/* nächste RasInfo: Adresse von RasInfo[3] */
	RasInfo[3].BitMap=&BitMap[3];
	RasInfo[3].RxOffset=0;
	RasInfo[3].RyOffset=0;
	RasInfo[3].Next=NULL;

	ViewPort[0].DxOffset=0;			/* Position vom ViewPort im View */
	ViewPort[0].DyOffset=0;
	ViewPort[0].DWidth=V1WIDTH;		/* Breite des ViewPorts */
	ViewPort[0].DHeight=V1HEIGHT;		/* Höhe des ViewPorts */
	ViewPort[0].RasInfo=&RasInfo[0];	/* Zeiger auf RasInfo */
	ViewPort[0].Modes=MODE1;		/* Darstellungsmodus */
	ViewPort[0].Next=&ViewPort[1];		/* nächster ViewPort */
	
	ViewPort[1].DxOffset=0;
	ViewPort[1].DyOffset=110;
	ViewPort[1].DWidth=V2WIDTH;
	ViewPort[1].DHeight=V2HEIGHT;
	ViewPort[1].RasInfo=&RasInfo[1];
	ViewPort[1].Modes=MODE2;
	ViewPort[1].Next=&ViewPort[2];

	ViewPort[2].DxOffset=0;
	ViewPort[2].DyOffset=170;
	ViewPort[2].DWidth=V3WIDTH;
	ViewPort[2].DHeight=V3HEIGHT;
	ViewPort[2].RasInfo=&RasInfo[2];
	ViewPort[2].Modes=MODE3;
	ViewPort[2].Next=NULL;
	
	ViewPort[0].ColorMap=(struct ColorMap*)GetColorMap(19);	/* Zeiger auf Frabwerte des Views */
	ViewPort[1].ColorMap=(struct ColorMap*)GetColorMap(16);
	ViewPort[2].ColorMap=(struct ColorMap*)GetColorMap(16);

	LoadRGB4(&ViewPort[0],&color1[0],19);	/* neue Farbwerte laden */
	LoadRGB4(&ViewPort[1],&color2[0],16);
	LoadRGB4(&ViewPort[2],&color3[0],16);

	for(i=0;i<DEPTHV1;i++)			
	{
		if((BitMap[0].Planes[i]=(PLANEPTR)
		   AllocRaster(V1WIDTH,V1HEIGHT))==NULL)
			Exit(NOT_ENOUGH_MEMORY);
		BltClear((UBYTE*)BitMap[0].Planes[i],
		   RASSIZE(V1WIDTH,V1HEIGHT),0);
	}
	
	for(i=0;i<DEPTHV2;i++)
	{
		if((BitMap[1].Planes[i]=(PLANEPTR)
		   AllocRaster(V2WIDTH,V2HEIGHT+700))==NULL)
			Exit(NOT_ENOUGH_MEMORY);
		BltClear((UBYTE*)BitMap[1].Planes[i],
		   RASSIZE(V2WIDTH,V2HEIGHT+700),0);
	}

	for(i=0;i<DEPTHV3;i++)
	{
		if((BitMap[2].Planes[i]=(PLANEPTR)
		   AllocRaster(V3WIDTH,V3HEIGHT+10))==NULL)
			Exit(NOT_ENOUGH_MEMORY);
		BltClear((UBYTE*)BitMap[2].Planes[i],
		   RASSIZE(V3WIDTH,V3HEIGHT+10),0);
	}

	for(i=0;i<DEPTHV3;i++)
	{
		if((BitMap[3].Planes[i]=(PLANEPTR)
		   AllocRaster(V3WIDTH,V3HEIGHT+10))==NULL)
			Exit(NOT_ENOUGH_MEMORY);
		BltClear((UBYTE*)BitMap[3].Planes[i],
		   RASSIZE(V3WIDTH,V3HEIGHT+10),0);
	}
	

	for(i=0;i<4;i++)
	{
		InitRastPort(&RastPort[i]);
		RastPort[i].BitMap=&BitMap[i];
	}

	MakeVPort(&View,&ViewPort[0]);
	MakeVPort(&View,&ViewPort[1]);
	MakeVPort(&View,&ViewPort[2]);

	MrgCop(&View);
	LoadView(&View);

	draw();
	
	LoadView(oldView);
	FreeMemory();
	return(0);
}

VOID draw()
{
	for(i=0;i<11;i++)
	{
		SetAPen(&RastPort[0],i+1);
		Move(&RastPort[0],i*31,0);
		Draw(&RastPort[0],i*31,V1HEIGHT-1);
		g=0,b=0,n=1;
		for(a=1;a<31;a++)
		{
			if(i==0 || i==3 || i==6 || i==9)
			{
				b=g+16;
			}
			if(i==1 || i==4 || i==7 || i==10)
			{
				b=g+32;
			}
			if(i==2 || i==5 || i==8)
			{
				b=g+48;
			}
			SetAPen(&RastPort[0],b);
			Move(&RastPort[0],a+i*31,0);
			Draw(&RastPort[0],a+i*31,V1HEIGHT-1);
			if(n>0)		g++;
			if(n<0)		g--;
			if(g==15)	n=-1;
		}
	}

	status=GetSprite(&SimpleSprite,1);
	if(status==-1)		exit(0);

	SimpleSprite.num=status;		/* Nummer des Sprites in Struktur */
	SimpleSprite.height=17;			/* Höhe des Sprites */
	SimpleSprite.y=20;			/* y-Position des Sprites */
	SimpleSprite.x=30;			/* x-Position des Sprites */
	
	ChipSpriteD=(UWORD*)AllocMem(sizeof(SpriteDaten),MEMF_CLEAR|MEMF_CHIP);
	if(ChipSpriteD==0)	exit(0);
	Help=ChipSpriteD;
	for(i=0;i<(sizeof(SpriteDaten)/sizeof(UWORD));i++)
	{
		*Help=SpriteDaten[i];
		Help++;
	}

	ChangeSprite(&ViewPort[0],&SimpleSprite,ChipSpriteD);

	SetDrMd(&RastPort[1],JAM1);
	SetAPen(&RastPort[1],0);

	z1=1,z2=5;
	for(j=1;j<8;j++)
	{
		SetAPen(&RastPort[1],j+1);
		n=1,a=0,b=16;
		if(j==2)	b=32;
		if(j==3)	b=48;
		if(j==5)	b=32;
		for(i=0;i<31;i++)
		{
			
			SetAPen(&RastPort[1],a+b);
			Move(&RastPort[1],0,i+(j*30));
			Draw(&RastPort[1],320,i+(j*30));
			if(n>0)		a++;
			if(n<0)		a--;
			if(a==15)	n=-1;
		}
	}

	for(i=1;i<16;i++)
	{
		SetAPen(&RastPort[1],i);
		Move(&RastPort[1],i*20+1,30);
		Draw(&RastPort[1],i*20+1,208);
	}

	SetDrMd(&RastPort[2],JAM1);
	SetAPen(&RastPort[2],1);
	
	n=0;
	for(n=0;n<2;n++)
	{	
		j=V3HEIGHT-10;
		for(i=0;i<15;i++)
		{
			data[n][i*8]=50*(n+1);
			data[n][i*8+1]=i+RUNTER;
			data[n][i*8+2]=i+(50*n);
			data[n][i*8+3]=i+RUNTER;
			data[n][i*8+4]=i+(50*n);
			data[n][i*8+5]=j+RUNTER;
			data[n][i*8+6]=50*(n+1);
			data[n][i*8+7]=j+RUNTER;
			j--;
		}
	}
	j=V3HEIGHT-10;
	for(i=0;i<15;i++)
	{
		data[2][i*8]=i+100;
		data[2][i*8+1]=RUNTER;
		data[2][i*8+2]=i+100;
		data[2][i*8+3]=j+RUNTER;
		data[2][i*8+4]=150-i;
		data[2][i*8+5]=j+RUNTER;
		data[2][i*8+6]=150-i;
		data[2][i*8+7]=RUNTER;
		j--;
	}
	
	for(a=0;a<3;a++)
	{
		n=1,j=0;
		for(i=0;i<15;i++)
		{
			SetAPen(&RastPort[2],j);
			PolyDraw(&RastPort[2],8,&data[a][i*8]);
			if(n>0)		j++;
			if(n<0)		j--;
			if(j==7)	n=-1;
		}	
		Move(&RastPort[2],50,0);
	}	

	SetDrMd(&RastPort[3],JAM1);
	SetAPen(&RastPort[3],1);
	
	j=0;	
	for(i=0;i<V3HEIGHT+9;i++)
	{
		Move(&RastPort[3],0,i);
		Draw(&RastPort[3],V3WIDTH-1,i);
		j++;
		if(j==8)	j=0;
		SetAPen(&RastPort[3],j);
	}

	Delay(100);
	
	g=1,h=1,a=0,f=0;
	while((*LeftMouse&0x40)==0x40)
	{
	for(i=0;i<240;i++)
	   {
		RasInfo[1].RyOffset=(int)g/1.25;
		RasInfo[2].RxOffset=(int)i/.1875;
		RasInfo[3].RyOffset=a;
		MakeVPort(&View,&ViewPort[1]);		
		MakeVPort(&View,&ViewPort[2]);
		MoveSprite(&ViewPort[0],&SimpleSprite,g+30,20+(g/4));
		WaitBOVP(ViewPort[2]);
		MrgCop(&View);
		g=g+h;
		if(f==2)
		{
			a=a+1;
			f=0;
		}
		if(a==8)	a=0;
		f=f+1;
	   }
		h=h*(-1);
	}
}

VOID FreeMemory()
{
   for (i=0;i<DEPTHV1;i++)
      FreeRaster(BitMap[0].Planes[i],V1WIDTH,V1HEIGHT);
   for (i=0;i<DEPTHV2;i++)
      FreeRaster(BitMap[1].Planes[i],V2WIDTH,V2HEIGHT+700);
   for (i=0;i<DEPTHV3;i++)
      FreeRaster(BitMap[2].Planes[i],V3WIDTH,V3HEIGHT+10);
   for (i=0;i<DEPTHV3;i++)
      FreeRaster(BitMap[3].Planes[i],V3WIDTH,V3HEIGHT+10);
                       /* BitPlane Speicher zurückgeben */
   FreeColorMap(ViewPort[0].ColorMap);
   FreeColorMap(ViewPort[1].ColorMap);
   FreeColorMap(ViewPort[2].ColorMap);
                            /* ColorMap Speicher, der mit */
                            /* GetColorMap() belegt wurde */
                            /* wieder freigeben           */
   FreeVPortCopLists(&ViewPort[0]);
   FreeVPortCopLists(&ViewPort[1]);
   FreeVPortCopLists(&ViewPort[2]);
                                 /* Speicher für ViewPort */
                                 /* CopperListe           */
                                 /* v. MakeVPort() belegt */
   FreeCprList(View.LOFCprList);
   FreeCprList(View.SHFCprList);
                                     /* View CopperListen */
   FreeSprite(status);
   FreeMem(ChipSpriteD,sizeof(SpriteDaten));

   CloseLibrary(GfxBase);
                                     /* Schliesse Library */
}
