/*************************************************************************
/*                                                                       *
/* C-Beispielprogramm für die Get-It ( Diskettenmagazin der AIT-UG )     *
/* geschrieben von Peter Fischer, RP.-Ebert-Str. 6, D-3257 Springe 1     *
/*                                                                       *
/* Kurs 9 : Systemroutinen                                               *
/* Datum : 8.10.89                                                       *
/*                                                                       *
/* Copyrights (c)'89 by PeeF.                                            *
/* Der ausführbare Code ist Public Domain in bester Manier.              *
/* Der Quellcode darf von jedem/r GetiT-Leser/in benutzt werden, wie es  *
/* in seinem/ihrem Interesse liegt.                                      *
/*                                                                       *
/*************************************************************************/
/*                                                                       *
/* Kompilieren mit                                                       *
/* cc +p c9_1                                                            *
/* Linken mit                                                            *
/* ln -cl32 -a32 c9_1                                                    *
/*                                                                       *
/*************************************************************************/

#include <intuition/intuition.h>
#include <exec/exec.h>
#include <graphics/gfx.h>
#include <stdio.h>
#include <libraries/arpbase.h>

/* Für AmigaDOS & Co                                                     */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct ArpBase *ArpBase = NULL;

/* Alle die Variablen für Intuition für Screens und Fenster.             */
struct NewScreen NewScr =
{ 0,0,640,256,4,11,2,HIRES,CUSTOMSCREEN,
  NULL,"Ein Screen für alle Fälle ! Folge -9-",NULL,NULL
};
struct Screen *Scr = NULL;

/* Diesmal brauchen wir ein paar mehr Fensterle... */
struct NewWindow NF[6] =
{ { 0,10,320,10,0,1,
    CLOSEWINDOW,
    WINDOWCLOSE | NOCAREREFRESH | ACTIVATE,
    NULL,NULL,NULL,
    NULL,NULL,300,10,640,256,CUSTOMSCREEN
  },
  { 320,10,320,100,2,1,
    CLOSEWINDOW,
    WINDOWCLOSE | NOCAREREFRESH,
    NULL,NULL,NULL,
    NULL,NULL,300,10,640,256,CUSTOMSCREEN
  },
  { 0,20,320,20,3,1,
    CLOSEWINDOW,
    WINDOWCLOSE | NOCAREREFRESH,
    NULL,NULL,NULL,
    NULL,NULL,300,10,640,256,CUSTOMSCREEN
  },
  { 0,40,320,40,4,1,
    CLOSEWINDOW,
    WINDOWCLOSE | NOCAREREFRESH,
    NULL,NULL,NULL,
    NULL,NULL,300,10,640,256,CUSTOMSCREEN
  },
  { 0,80,320,80,5,1,
    CLOSEWINDOW,
    WINDOWCLOSE | NOCAREREFRESH,
    NULL,NULL,NULL,
    NULL,NULL,300,10,640,256,CUSTOMSCREEN
  },
  { 320,110,320,140,6,1,
    CLOSEWINDOW,
    WINDOWCLOSE | NOCAREREFRESH,
    NULL,NULL,NULL,
    NULL,NULL,300,10,640,256,CUSTOMSCREEN
  }
};

/* ...und dementsprechend auch hier jeweils sechs Stück. */
struct Window *Fenster[6] = { NULL,NULL,NULL,NULL,NULL,NULL };
struct RastPort *rp[6];
/* Für den Titel auf dem Screen. */
char title[6][30];

/* Festlegung der Farben.                                                */
int Farbe[16][3] =
{ {  0, 0, 0 },                            /* Schwarz                    */
  { 15,15,15 },{ 12,12,12 },{  8, 8, 8 },  /* WEISS bis grau             */
  {  8, 0, 0 },{ 12, 0, 0 },{ 15, 0, 0 },  /* Rot                        */
  {  0, 8, 0 },{  0,12, 0 },{  0,15, 0 },  /* Grün                       */
  {  0, 0, 8 },{  0, 0,12 },{  0, 0,15 },  /* Blau                       */
  {  8, 0, 8 },{ 12, 0,12 },{ 15, 0,15 },  /* Lila                       */
};

/*************************************************************************
 * MEIN AIT-Zeiger. Keine COPYRIGHTS, darf jeder benutzen !              */
UWORD ptr[] =
{ 0x00  ,0x00,
  0x0000,0x0100,  0x0000,0x0280,  0x0000,0x0440,  0x0000,0x0280,
  0x0000,0x0100,  0x0000,0x0000,  0x31BF,0x1081,  0x798C,0x2884,
  0x798C,0x2884,  0x798C,0x2884,  0x798C,0x2884,  0xFD8C,0x0484,
  0xCD8C,0x4484,  0xCD8C,0x4484,  0xCD8C,0x4484,  0x0000,0x0000,
  0x00  ,0x00
}, *cptr = NULL;

/*************************************************************************
/* Die Images sind mit Image-Ed generiert.                               */
/* Thanks to Jonathan Potter, aber massig Fehler im Programm ! Guru, ick */
/* hör Dir trapsen.                                                      */
/* Die Images werden für die Menüs gebraucht, menu[5][x].                */
/* Start of Image data */
USHORT 
  ImageData1[]=
  { /* Plane 0 */
    0xfffc, 0xfffc, 0xf07c, 0xf07c, 0xf07c, 0xf8fc, 0xfdfc, 0xfffc, 
    0xfffc, 0xfffc, 0xdfdc, 0xf8fc, 0xf8fc, 0xfafc, 0xfafc, 0xfffc, 
    0xfffc, 0x0000, 
    /* Plane 1 */
    0x0002, 0x0002, 0x0f82, 0x0f82, 0x0f82, 0x0702, 0x0202, 0x0002, 
    0x0002, 0x0002, 0x2022, 0x0702, 0x0702, 0x0502, 0x0502, 0x0d82, 
    0x0002, 0xfffe, 
    /* Plane 2 */
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0700, 
    0x0f80, 0x1740, 0x0700, 0x0700, 0x0700, 0x0500, 0x0500, 0x0d80, 
    0x0000, 0x0000, 
    /* Plane 3 */
    0x0000, 0x0000, 0x0f80, 0x0880, 0x0880, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0d80, 
    0x0000, 0x0000
  }, 
  ImageData2[]=
  { /* Plane 0 */
    0xfffc, 0xfffc, 0xf07c, 0xf07c, 0xb07c, 0xf8fc, 0xfdfc, 0xfffc, 
    0xfffc, 0xfffc, 0xffdc, 0xf8fc, 0xf8fc, 0xfafc, 0xfafc, 0xfffc, 
    0xfffc, 0x0000, 
    /* Plane 1 */
    0x0002, 0x0002, 0x0f82, 0x0f82, 0x4f82, 0x0702, 0x0202, 0x0002, 
    0x0002, 0x0002, 0x0022, 0x0702, 0x0702, 0x0502, 0x0502, 0x0d82, 
    0x0002, 0xfffe, 
    /* Plane 2 */
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2000, 0x1000, 0x0f00, 
    0x0780, 0x0740, 0x0700, 0x0700, 0x0700, 0x0500, 0x0500, 0x0d80, 
    0x0000, 0x0000, 
    /* Plane 3 */
    0x0000, 0x0000, 0x0f80, 0x0880, 0x0880, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0d80, 
    0x0000, 0x0000
  }, 
  ImageData3[]=
  { /* Plane 0 */
    0x0000, 0x0818, 0x0000, 0x0000, 0x1800, 0x0000, 0x003c, 0x3e38, 
    0x0000, 0x0066, 0x1818, 0x0000, 0x007e, 0x1818, 0x0000, 0x0060, 
    0x1a18, 0x0000, 0x003c, 0x0c3c, 0x0000, 0x0000, 0x0000, 0x0000, 
    /* Plane 1 */
    0x3c00, 0x0000, 0x7e00, 0x6600, 0x0000, 0x5a00, 0xc000, 0x0000, 
    0x1800, 0xce00, 0x0000, 0x1800, 0xc600, 0x0000, 0x1800, 0x6600, 
    0x0000, 0x1800, 0x3e00, 0x0000, 0x3c00, 0x0000, 0x0000, 0x0000, 
    /* Plane 2 */
    0x3c00, 0x0000, 0x7e00, 0x6600, 0x0000, 0x5a00, 0xc000, 0x0000, 
    0x1800, 0xce00, 0x0000, 0x1800, 0xc600, 0x0000, 0x1800, 0x6600, 
    0x0000, 0x1800, 0x3e00, 0x0000, 0x3c00, 0x0000, 0x0000, 0x0000, 
    /* Plane 3 */
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  }, 
  ImageData4[]=
  { /* Plane 0 */
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    /* Plane 1 */
    0x7800, 0x0000, 0xf800, 0x3000, 0x0000, 0xcc00, 0x3000, 0x0000, 
    0xc600, 0x3000, 0x0000, 0xe600, 0x3000, 0x0000, 0x0600, 0xb400, 
    0x0000, 0xcc00, 0xfc00, 0x0000, 0x7800, 0x0000, 0x0000, 0x0000, 
    /* Plane 2 */
    0x0078, 0x6078, 0x0000, 0x0030, 0xb00c, 0x0000, 0x0030, 0x30fc, 
    0x0000, 0x0030, 0x30cc, 0x0000, 0x0038, 0xf878, 0x0000, 0x0000, 
    0x3000, 0x0000, 0x0030, 0x2000, 0x0000, 0x0000, 0x0000, 0x0000, 
    /* Plane 3 */
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  }, 
  *ChipData1,
  *ChipData2,
  *ChipData3,
  *ChipData4;
/* End of Image data */

struct Image 
  Image1=
  { 0,0, /* LeftEdge, TopEdge */
    15,18,4, /* Width, Height, Depth */
    NULL, /* ImageData */
    0xf,0x0, /* PlanePick, PlaneOnOff */
    NULL /* Next Image */
  },
  Image2=
  { 0,0, /* LeftEdge, TopEdge */
    15,18,4, /* Width, Height, Depth */
    NULL, /* ImageData */
    0xf,0x0, /* PlanePick, PlaneOnOff */
    NULL /* Next Image */
  },
  Image3=
  { 0,0, /* LeftEdge, TopEdge */
    40,8,4, /* Width, Height, Depth */
    NULL, /* ImageData */
    0xf,0x0, /* PlanePick, PlaneOnOff */
    NULL /* Next Image */
  },
  Image4=
  { 0,0, /* LeftEdge, TopEdge */
    40,8,4, /* Width, Height, Depth */
    NULL, /* ImageData */
    0xf,0x0, /* PlanePick, PlaneOnOff */
    NULL /* Next Image */
  };
/* End of Image-Ed Image generation */

/*************************************************************************
/* Die Texte für die Items.                                              */
struct IntuiText
  /* menu[0] */
  text011 = { 3,0,JAM1,0,0,NULL,"Beispiel für Text",NULL },
  text012 = { 2,0,JAM1,0,0,NULL,"Noch eins",NULL },
  text021 = { 2,0,JAM1,0,0,NULL,"  Zweites Menü",NULL },
  /* menu[1] */
  text111 = { 11,1,JAM1,0,0,NULL,"Neues Menü",NULL },
  text112 = { 12,1,JAM1,0,0,NULL,"Neues Glück",NULL },
  text121c = { 6,1,JAM1,0,30,NULL,"Super, nich ?",NULL },
  text121b = { 5,1,JAM1,0,20,NULL,"Wirklich riesig !",&text121c },
  text121a = { 4,1,JAM1,0,10,NULL,"alles nur eine Box.",&text121b },
  text121 = { 13,1,JAM1,0,0,NULL,"Nun eine Riesen-Box,",&text121a },
  /* menu[2] */
  text211 = { 2,1,JAM1,0,0,NULL,"Hier is nix mehr los !",NULL },
  /* menu[3] */
  /* FEHLANZEIGE ! */
  /* menu[4] */
  text411  = { 6,1,JAM1,0,0,NULL,"Was gibts Neues ?",NULL },
  text421a = { 4,1,JAM2,0,0,NULL,"Please klick me !",NULL },
  text421b = { 5,1,JAM2,0,0,NULL,"Thanks !         ",NULL },
  /* menu[5] */
  text511 = { 11,1,JAM1,0,0,NULL,"Image",NULL },
  text521 = { 11,1,JAM1,0,0,NULL,"Image",NULL };

/*************************************************************************
/* Daten für die Items.                                                  */
struct MenuItem
  /* menu[0] */
  item021 = 
  { NULL   , 0, 0,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT,
    NULL,&text021,NULL,NULL,NULL,NULL 
  },
  item012 = 
  { NULL   , 0,15,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP,
    NULL,&text012,NULL,NULL,NULL,NULL 
  },
  item011 = 
  { &item012, 0, 0,100,10,ITEMTEXT | ITEMENABLED | HIGHCOMP,
    NULL,&text011,NULL,NULL,NULL,NULL 
  },

  /* menu[1] */
  item121 = 
  { NULL   ,10, 0,160,50,ITEMTEXT | ITEMENABLED | HIGHBOX,
    NULL,&text121,NULL,NULL,NULL,NULL 
  },
  item112 = 
  { NULL   , 0,15,100,10,ITEMTEXT | ITEMENABLED | HIGHBOX,
    NULL,&text112,NULL,NULL,NULL,NULL 
  },
  item111 = 
  { &item112, 0, 0,100,10,ITEMTEXT | HIGHBOX,
    NULL,&text111,NULL,NULL,NULL,NULL 
  },

  /* menu[2] */
  item211 = 
  { NULL, 0, 0,200,10,ITEMTEXT | ITEMENABLED | HIGHCOMP,
    NULL,&text211,NULL,NULL,NULL,NULL 
  },

  /* menu[3] is nich. */
  /* menu[4] */
  item421 = 
  { NULL   , 0, 0,100,10,ITEMTEXT | ITEMENABLED | HIGHIMAGE,
    NULL,&text421a,&text421b,NULL,NULL,NULL 
  },
  item411 = 
  { NULL, 0, 0,100,10,ITEMTEXT | ITEMENABLED | HIGHNONE,
    NULL,&text411,NULL,NULL,NULL,NULL 
  },

  /* menu[5] */
  item521 = 
  { NULL   , 0, 0,17,20,ITEMENABLED | HIGHIMAGE,
    NULL,&Image1,&Image2,NULL,NULL,NULL 
  },
  item511 = 
  { NULL, 0, 0,42,10,ITEMENABLED | HIGHIMAGE,
    NULL,&Image3,&Image4,NULL,NULL,NULL 
  };

/*************************************************************************
/* Daten für die Menüs.                                                  */
struct Menu menu[][2] =
{ { { NULL       ,160,0, 90,10,MENUENABLED,"Hallo",&item021 },
    { &menu[0][0],  0,0,150,10,MENUENABLED,"Nur ein Beispiel",&item011 }
  },
  { { NULL       ,150,0, 90,10,MENUENABLED,"Menüs",&item111 },
    { &menu[1][0],  0,0,140,10,MENUENABLED,"Kein Sinn",&item121 }
  },
  { { NULL       , 60,0, 90,10,MENUENABLED," is it !",&item211 },
    { &menu[2][0],  0,0, 50,10,MENUENABLED,"GetiT",NULL }
  },
  { { NULL       , 70,0, 90,10,NULL," nix !",NULL },
    { &menu[3][0],  0,0, 60,10,NULL,"Hier is",NULL }
  },
  { { NULL       , 50,0, 90,10,MENUENABLED,"is Spitze !",&item411 },
    { &menu[4][0],  0,0, 45,10,MENUENABLED,"AMIGA ",&item421 }
  },
  { { NULL       , 40,0, 90,10,MENUENABLED,"PeeF !",&item511 },
    { &menu[5][0],  0,0, 36,10,MENUENABLED,"© by",&item521 }
  }
};

/*************************************************************************
/* Start des Hauptprogramms.                                             */
main()
{ struct IntuiMessage *msg;
  int i;
  static char fehler[] = "Kein Platz für Image.";

  /* Alle Initialisationen. ( Watn Wort )                                */
  init();

  ChipData1 = AllocMem ( 4 * 15 * 18 * sizeof ( USHORT ), MEMF_CHIP | MEMF_CLEAR );
  if ( ChipData1 == NULL )
    notaus ( fehler );
  CopyMem ( ImageData1,ChipData1,4 * 15 * 18 * sizeof ( USHORT ) );
  Image1.ImageData = ChipData1;

  ChipData2 = AllocMem ( 4 * 15 * 18 * sizeof ( USHORT ), MEMF_CHIP | MEMF_CLEAR );
  if ( ChipData2 == NULL )
    notaus ( fehler );
  CopyMem ( ImageData2,ChipData2,4 * 15 * 18 * sizeof ( USHORT ) );
  Image2.ImageData = ChipData2;

  ChipData3 = AllocMem ( 4 * 40 * 8 * sizeof ( USHORT ), MEMF_CHIP | MEMF_CLEAR );
  if ( ChipData3 == NULL )
    notaus ( fehler );
  CopyMem ( ImageData3,ChipData3,4 * 40 * 8 * sizeof ( USHORT ) );
  Image3.ImageData = ChipData3;

  ChipData4 = AllocMem ( 4 * 40 * 8 * sizeof ( USHORT ), MEMF_CHIP | MEMF_CLEAR );
  if ( ChipData4 == NULL )
    notaus ( fehler );
  CopyMem ( ImageData4,ChipData4,4 * 40 * 8 * sizeof ( USHORT ) );
  Image4.ImageData = ChipData4;

  for ( i = 0; i < 6; i++ )
  { /* Menus setzen.                                                     */
    SetMenuStrip ( Fenster[i],&menu[i][1] );
    /* Hinweis auf Menus.                                                */
    sprintf ( title[i],"Fenster %d",i );
    SetWindowTitles ( Fenster[i],"MenüTest",title[i] );
    /* MEINEN Mauszeiger setzen.                                         */
    SetPointer ( Fenster[i],cptr,16,16,-8,-3 );
  }
  Wait ( 1 << Fenster[0]->UserPort->mp_SigBit );
  msg = GetMsg ( Fenster[0]->UserPort );
  ReplyMsg ( msg );
  notaus( NULL );
}

/* Routine, die alles wieder aus dem Speicher entfernt ( bzw entfernen   *
/* soll) . Gibt im Fehlerfall eine Meldung auf den Bildschirm aus, auch  *
/* für WORKBENCHer wie Jochen und Magnus.                                */
notaus ( txt )
char *txt;
{ FILE *aus,*fopen();
  int i;

  /* Pointer wieder restaurieren. Eigentlich wohl überflüssig, oder ?    */
  for ( i = 0; i < 6; i++ )
    ClearPointer ( Fenster );
  /* Alles wech !                                                        */
  if ( cptr != NULL )
    FreeMem( cptr,36 * sizeof(UWORD) );
  for ( i = 0; i < 6; i++ ) 
    if ( Fenster[i] != NULL )
      CloseWindow ( Fenster[i] );
  FreeMem ( ChipData1,4 * 15 * 18 * sizeof ( USHORT ) );
  FreeMem ( ChipData2,4 * 15 * 18 * sizeof ( USHORT ) );
  FreeMem ( ChipData3,4 * 40 *  8 * sizeof ( USHORT ) );
  FreeMem ( ChipData4,4 * 40 *  8 * sizeof ( USHORT ) );
  if ( Scr != NULL )
    CloseScreen ( Scr );
  if ( ArpBase != NULL )
    CloseLibrary ( ArpBase );
  /* Ausgabe der Fehlermeldung.                                          */
  if ( txt != NULL )
  { aus = fopen ( "CON:0/108/320/80/ABBRUCH","w" );
    fprintf ( aus,"%s\n",txt );
    fprintf ( aus,"Das Programm wird abgebrochen !\n" );
    Delay ( 150L );
    fclose ( aus );
    exit(100);
  }
  exit ( 0 );
}

/* Initialisierungen                                                     */
init()
{ int i;

  ArpBase = OpenLibrary ( "arp.library",0 );
  if ( ArpBase == NULL )
    notaus ( "arp.library läßt sich nicht öffnen !" );

  IntuitionBase = ArpBase->IntuiBase;
  GfxBase = ArpBase->GfxBase;

  Scr = OpenScreen ( &NewScr );
  if ( Scr == NULL )
    notaus ( "Screen läßt sich nicht öffnen !" );

  for ( i = 0; i < 16; i++ )
    SetRGB4 ( &(Scr->ViewPort),i,Farbe[i][0],Farbe[i][1],Farbe[i][2] );

  for ( i = 0; i < 6; i++ )
  { NF[i].Screen = Scr;
    Fenster[i] = OpenWindow( &NF[i] );
    if ( Fenster[i] == NULL )
      notaus ( "Fenster läßt sich nicht öffnen !" );
    rp[i] = Fenster[i]->RPort;
  }

  cptr = AllocMem ( 36 * sizeof(UWORD),MEMF_CHIP );
  if ( cptr == NULL )
    notaus( "Zu wenig Speicher für den Pointer !" );
  for ( i = 0; i < 36; i++ )
    cptr[i] = ptr[i];
}
