/* Beispielprogramm 'Amigazette' mit "double buffered display" */
/* Programmiert von Marcel Achermann */

#include "viewport.h"

#define DEPTH 4                   /* Anzahl der Bitplanes   */
#define WIDTH 320                 /* Breite des Screens */
#define HEIGHT 200                /* Hoehe  des Screens */
#define GESCH 11                  /* Geschwindigkeit der Linie(n) */
#define AN 11                      /* Linienanzahl */

struct View v1,v2,*oldview;
struct ViewPort vp1,vp2;
struct ColorMap *cm1,*cm2;
struct RasInfo ri1,ri2;
struct BitMap b1,b2;
struct RastPort rastport,*rp;
extern struct ColorMap *GetColorMap();
USHORT colortable[]={
  0x000,0xf0f,0xe0e,0xc0c,0xa0a,0x909,0x808,0x707,
  0x606,0x505,0x404,0x303,0x202,0x101,0xf00,0xc00  };
USHORT *colorpalette,visible=1;
struct GfxBase *GfxBase;
struct Task *task;
unsigned char *displaymem;

/*-----------------------------------------Variablen fuer Linienpart----*/
int y1,y2,x1,x2,vx1,vy1,vx2,vy2,w,h;
int xa[AN],xb[AN],ya[AN],yb[AN];
/*-----------------------------------------Gemischte Variablen----------*/
int i,farbe;
/*-----------------------------------------Variablen fuer Read Amigaz.--*/
USHORT incv,maxy,count;
int txty[8];
int vy;
int txtfarbe[]={1,4,6,8,9,10,11,12 };     /* Farben des Textes */


main()
{
  Init();

/*---------------------------------------------Read the Amigazette !------*/
  vy=1; incv=1;
  maxy=160;
  for(i=0;i<8;i++) txty[i]=50;
  while(peekb(0xbfe001)!=0xbc) {
     Switch();
     for(i=7;i>=0;i--) {
       SetAPen(rp,txtfarbe[i]);
       Move(rp,75,txty[i]);
       Text(rp,"Ready Software Ltd/POLAND",25);
     }
     for(i=7;i>0;i--) txty[i]=txty[i-1];
     txty[0]=txty[0]+vy;
     vy+=incv;
     if(txty[0]>maxy) {
       vy=-16;
       count++;
     }
     if(count>3) { incv=0; vy=0; break; }
  }
/*------------------------------------------------------Linien----------*/

  task=FindTask(0);                    /* Damit die Maus keinen neg.*/
  SetTaskPri(task,30);                 /* Einfluss mehr hat.*/

                                       /* Initialisierung der Variablen */
  vx1=3;   x1=30;                      /* v..: Geschwindigkeiten der Punkte */
  vy1=2;   y1=100;                     /* x./y.: Koordinaten der Punkte */
  vx2=-3;  x2=290;
  vy2=-2;  y2=100;
  w=WIDTH-1;  h=HEIGHT-1;              /* Randlinien fuer die Linienbeweg.*/

  InitNachzug();                       /* Initialisieren der Nachzuegler */
  while(peekb(0xbfe001)!=0xbc) {       /* Solange linke MausTaste nicht */
                                       /* gedrueckt ist... */
      Nachzug();
      SetAPen(rp,1);
      Move(rp,x1,y1);
      Draw(rp,x2,y2);
      x1+=vx1;
      x2+=vx2;
      y1+=vy1;
      y2+=vy2;
      if (x1>=w) { x1=w; vx1=-RangeRand(GESCH); }  /* wenn auf Rand gestos- */
      if (x2>=w) { x2=w; vx2=-RangeRand(GESCH); }  /* sen, setze Geschwin-  */
      if (x1<=0) { x1=0; vx1=RangeRand(GESCH); }   /* digkeiten neu (Zufall)*/
      if (x2<=0) { x2=0; vx2=RangeRand(GESCH); }
      if (y1>=h) { y1=h; vy1=-RangeRand(GESCH); }
      if (y2>=h) { y2=h; vy2=-RangeRand(GESCH); }
      if (y1<=0) { y1=0; vy1=RangeRand(GESCH); }
      if (y2<=0) { y2=0; vy2=RangeRand(GESCH); }
      SetAPen(rp,14);
      Move(rp,102,78);                             /* Zeichne den Txt in der */
      Text(rp,"Ready Software Ltd",18);                    /* Mitte */
      SetAPen(rp,15);
      Move(rp,79,103);
      Text(rp,"       P.Koziarski   ",21);
      Move(rp,83,113);
      Text(rp,"   ul.Pasieczna 4a/10",21);
      Move(rp,94,123);
      Text(rp,"PL-45-087 OPOLE/POLAND",22);
      Move(rp,158,125);

      SetAPen(rp,14);
      Move(rp,55,140);
      Text(rp,"Please write us or call 39754",29);
      SetAPen(rp,2);
      Move(rp,50,167);
      Text(rp,"Greetings to all our friends",28);
      Switch();                         /* Umschalten */
  }
  FreeMemory();
}


InitNachzug()                           /* Initialisieren der Nachzuegler- */
{                                       /* koordinaten */
  for(i=0;i<AN;i++) {
      xa[i]=x1; xb[i]=x2;
      ya[i]=y1; yb[i]=y2;
  }
}


Nachzug()
{
  farbe=AN+2;
  for(i=AN-1;i>=0;i--) {             /* Zeichne Nachzuegler */
      SetAPen(rp,farbe);
      Move(rp,xa[i],ya[i]);
      Draw(rp,xb[i],yb[i]);
      xa[i]=xa[i-1];
      xb[i]=xb[i-1];
      ya[i]=ya[i-1];
      yb[i]=yb[i-1];
      farbe--;
  }
  xa[0]=x1; xb[0]=x2; ya[0]=y1; yb[0]=y2;
}



Init()      
 {
  int i;

  GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0);
  if (GfxBase == NULL) exit(100);

  oldview=GfxBase->ActiView;

  InitView(&v1);
  InitView(&v2);

  InitVPort(&vp1);
  InitVPort(&vp2);

  v1.ViewPort=&vp1;
  v2.ViewPort=&vp2;

  InitBitMap(&b1,DEPTH,WIDTH,HEIGHT);
  for(i=0;i<DEPTH;i++) {
    b1.Planes[i]=(PLANEPTR)AllocRaster(WIDTH,HEIGHT);
    if (b1.Planes[i]==NULL) exit(200);
  }

  InitBitMap(&b2,DEPTH,WIDTH,HEIGHT);
  for(i=0;i<DEPTH;i++) {
    b2.Planes[i]=(PLANEPTR)AllocRaster(WIDTH,HEIGHT);
    if (b2.Planes[i]==NULL) exit(300);
  }

  ri1.BitMap=&b1;      /* RasInfo zeigt auf BitMap */
  ri1.RxOffset=0;      /* Verschiebung des 0-Punkts im Grafikspeicher */
  ri1.RyOffset=0;
  ri1.Next=NULL;       /* Naechster RasInfo: Keiner */

  ri2.BitMap=&b2;
  ri2.RxOffset=0;
  ri2.RyOffset=0;
  ri2.Next=NULL;

  cm1=GetColorMap(DEPTH*DEPTH);
  if(cm1==NULL) exit(300);
  colorpalette=(unsigned short *)cm1->ColorTable;
  for(i=0;i<(DEPTH*DEPTH);i++) {
    *colorpalette++=colortable[i];
  }

   cm2=GetColorMap(DEPTH*DEPTH);
  if(cm2==NULL) exit(400);
  colorpalette=(unsigned short *)cm2->ColorTable;
  for(i=0;i<(DEPTH*DEPTH);i++) {
    *colorpalette++=colortable[i];
  }


  vp1.DWidth=WIDTH;   /* Die Breite des ViewPorts */
  vp1.DHeight=HEIGHT; /* Die Hoehe des ViewPorts  */
  vp1.RasInfo=&ri1;    /* Zeigt auf die RasInfo-Struktur  */
  vp1.ColorMap=cm1;    /* Zeigt auf die ColorMap-Struktur */

  vp2.DWidth=WIDTH;
  vp2.DHeight=HEIGHT;
  vp2.RasInfo=&ri2;
  vp2.ColorMap=cm2;

  InitRastPort(&rastport);

  MakeVPort(&v1,&vp1);
  MrgCop(&v1);

  MakeVPort(&v2,&vp2);
  MrgCop(&v2);

  for(i=0;i<DEPTH;i++) {
    displaymem=(unsigned char *)b1.Planes[i];
    BltClear(displaymem,RASSIZE(WIDTH,HEIGHT),0);
  }

  for(i=0;i<DEPTH;i++) {
    displaymem=(unsigned char *)b2.Planes[i];
    BltClear(displaymem,RASSIZE(WIDTH,HEIGHT),0);
  }

  LoadView(&v1);

  rastport.BitMap=&b2;
  rp=&rastport;

  SetAPen(rp,1);
  SetBPen(rp,0);
  SetDrMd(rp,JAM1);
}

FreeMemory()
{
  int i;
  LoadView(oldview);

  for(i=0;i<DEPTH;i++) {
    FreeRaster(b1.Planes[i],WIDTH,HEIGHT);
    FreeRaster(b2.Planes[i],WIDTH,HEIGHT);
  }

  FreeColorMap(cm1);           /* Farbspeicher freimachen */
  FreeColorMap(cm2);
  FreeVPortCopLists(&vp1);     /* Copper Lists freimachen (Wurden vom */
  FreeVPortCopLists(&vp2);
  FreeCprList(v1.LOFCprList);  /* Copper gebraucht */
  FreeCprList(v2.LOFCprList);

  CloseLibrary(GfxBase);      /* graphics.library loslassen */

  exit(0);                    /* Ade ! */
}


Switch()                      /* Umschalten des Viewports/Bitmap */
{
  int a;
  if(visible==1) {
    visible=2;
    WaitBOVP(&vp1);
    LoadView(&v2);
    rastport.BitMap=&b1;
    for(a=0;a<DEPTH;a++) BltClear((unsigned char *)b1.Planes[a],RASSIZE(WIDTH,HEIGHT),0);
  }
  else {
    visible=1;
    WaitBOVP(&vp2);
    LoadView(&v1);
    rastport.BitMap=&b2;
    for(a=0;a<DEPTH;a++) BltClear((unsigned char *)b2.Planes[a],RASSIZE(WIDTH,HEIGHT),0);
  };
}
     
  

